TinaCMS 落地页内容建模实战:解读 kitchen-sink 首页 home.md 的 blocks 结构
2026/9/14 19:54:38 网站建设 项目流程

TinaCMS 落地页内容建模实战:解读 kitchen-sink 首页 home.md 的 blocks 结构

【免费下载链接】tinacmsTinaCMS is the leading open-source headless CMS that supports Markdown and Visual Editing. Your content is stored in your own GitHub repo 🦙 ❤️项目地址: https://gitcode.com/GitHub_Trending/ti/tinacms

home.md是 TinaCMS 仓库中 kitchen-sink 示例(Next.js / Astro / Hugo / React 多框架版本)共享的首页内容文件,它以 Markdown frontmatter 中的blocks数组描述整张落地页的区块结构,是理解 TinaCMS「Git-backed 内容 + 可视化编辑」工作流的最佳入门样本。读完本文,你将掌握 TinaCMS 的页面级 collection 建模方式、hero / features / cta / testimonial 四个内置模板的数据契约、blocks 从前台数据到 React 组件的完整渲染链路,并能在自己的站点中按相同模式新增或调整页面区块。

home.md 在示例工程中的定位:共享内容、多框架渲染

文件位于 examples/shared/content/pages/home.md,是examples/shared共享内容目录的一部分。从仓库目录结构可以观察到,examples/next/kitchen-sinkexamples/astro/kitchen-sinkexamples/hugo/kitchen-sinkexamples/react/kitchen-sink等示例工程均未自带content/pages目录,而是统一复用examples/shared/content下的内容,再分别用 Next.js、Astro、Hugo、React 等不同技术栈渲染同一份数据,这本身就是 TinaCMS「内容与展示解耦」理念的直观体现。

home.md全文是一个标准的 Markdown frontmatter 文件,---之间只有blocks一个顶层键,其值为一个有序数组,依次声明了 4 个区块:

  1. hero(首屏横幅)
  2. features(特性列表)
  3. cta(行动号召)
  4. testimonial(用户引语)

每个区块对象都带有一个_template字段,用于指定它属于哪种模板类型——这正是 TinaCMS 的「blocks 模板系统」在数据层的落点:内容文件中只存结构化数据,区块的类型与字段结构由_template声明,而字段如何渲染则由前端组件决定。

认识 page collection:blocks 字段如何被建模

要让上述 Markdown 数据在 TinaCMS 后台可编辑,必须先有对应的 collection 定义。kitchen-sink 示例的 page collection 位于 examples/next/kitchen-sink/tina/collections/page.tsx:

const Page: Collection = { label: 'Pages', name: 'page', path: 'content/pages', format: 'md', ui: { router: ({ document }) => { const filepath = document._sys.breadcrumbs.join('/'); if (filepath === 'home') { return '/'; // 首页路由映射到站点根路径 } return `/${filepath}`; }, }, fields: [ { type: 'object', list: true, name: 'blocks', label: 'Sections', ui: { visualSelector: true }, templates: [ heroBlockSchema, featureBlockSchema, ctaBlockSchema, testimonialBlockSchema, contentBlockSchema, ], }, { name: 'image', label: 'Image', type: 'image', accept: 'image' }, ], };

关键点解读:

  • path: 'content/pages'将该 collection 绑定到内容目录下的pages文件夹,home.md正是该目录下的文档;
  • format: 'md'说明内容以 Markdown 存储,blocks数据序列化在 frontmatter 中;
  • blocks字段是type: 'object'+list: true的组合,即「对象数组」,每个数组元素从templates列表中按_template选择具体模板;
  • ui.visualSelector: true开启后台的可视化区块选择器,编辑器可以直接增删、排序、更换区块;
  • ui.router自定义前台预览路由:文件名home映射到/,其余页面映射到/<文件名>

值得一提的是,templates中声明的 5 种模板(hero、features、cta、testimonial、content)中,前 4 种恰好覆盖了home.md的 4 个区块,content模板则为其他页面(如 examples/shared/content/pages/projects-built-with-tina.md)提供富文本内容块能力。

逐块拆解 home.md:四个内置模板的数据契约

hero:首屏横幅

home.md中的 hero 区块数据:

- tagline: Open-source CMS headline: The best editor experience for your developer-first sites text: | Tina is an open-source, Git-backed CMS with the ability to add visual editing to your NextJS site actions: - label: Get Started type: button link: 'https://tina.io' color: default _template: hero

对应的模板 schema 定义在 examples/next/kitchen-sink/components/blocks/hero.tsx 的heroBlockSchema中,字段契约如下:

字段类型说明
taglinestring标题上方的小字标签,带胶囊背景
headlinestring大号主标题
textrich-text副文案,渲染为富文本(Markdown)
imageobject可选图片对象(src+alt),未设置则不渲染
backgroundImageimage可选背景图,accept: 'png'
actionsobject list按钮/链接列表(详见下文共享字段)
colorstring区块主题色:default/tint/primary

hero.tsx中还给出了模板的defaultItem(编辑器新增区块时的预填内容),且ui.previewSrc: '/blocks/hero.png'指定了后台的区块预览缩略图——这正是 examples/shared/public/blocks/hero.png 的用途。

从渲染组件看,text字段通过TinaMarkdown渲染并支持自定义 Markdown 组件(customComponents),actions则交由Actions布局组件输出按钮组;组件上到处可见data-tina-field={tinaField(data, 'xxx')}标记,这些标记是可视化编辑(inline editing)时定位 DOM 与字段映射的关键。

features:特性列表

home.md中的 features 区块声明了标题、描述和 3 个特性条目,每个条目包含图标、标题和说明文字:

- title: Features description: Everything you need to build a great content editing experience. items: - icon: { name: BiSearchAlt2, color: primary, style: circle } title: Query Your Content text: Use GraphQL to query your content in any way you need. - icon: { name: BiLayer, color: teal, style: circle } title: Build on Top of Your Components text: Tina works alongside your existing component library. - icon: { name: BiTerminal, color: green, style: circle } title: Command Line Quickstart text: Get started in minutes with a single CLI command. color: default _template: features

其模板 schema 位于 examples/next/kitchen-sink/components/blocks/features.tsx 的featureBlockSchema

  • title/description:区块标题与描述(描述使用textarea组件);
  • itemslist: true的对象数组,每个条目包含icon(复用iconSchema,配置name图标名、color主题色、style样式如circle)、titletextactions
  • ui.itemProps将条目列表的显示标签设为条目的title,便于后台识别;
  • 渲染组件对条目做了向后兼容处理:条目既可以是对象,也可以是纯字符串(简单卡片布局),说明 blocks 数据结构的演进需要兼顾旧数据。

cta:行动号召

- title: New to Tina? description: Learn the basics of the development workflow actions: - label: Check out the docs type: button link: 'https://tina.io/docs/' color: tint _template: cta

cta 模板(examples/next/kitchen-sink/components/blocks/cta.tsx)的数据结构最为精简:title+description+actions+color。渲染时标题居中、描述跟随、动作按钮以Actions组件渲染。这个区块常被用作落地页的转化收尾区域,color: tint让它在页面中呈现与 hero(default)不同的底色层次。

testimonial:用户引语

- quote: 'There are only two hard things in Computer Science: cache invalidation and naming things.' author: Phil Karlton color: primary _template: testimonial

testimonial 模板(examples/next/kitchen-sink/components/blocks/testimonial.tsx)由quote(textarea)、authorcolor三个字段构成,渲染为带装饰性引号的大号块引用(blockquote),color: primary时使用高对比的主题色背景。有趣的是,该模板 schema 中的defaultItem恰好就是 home.md 里这条著名的 Phil Karlton 语录,说明这段示例内容正是从模板默认项沿用而来的。

共享字段:actions 与 color 的复用设计

四个区块反复出现actionscolor两个字段,它们不是各自复制粘贴,而是抽取自 examples/next/kitchen-sink/tina/schemas/shared-fields.ts,这是 TinaCMS schema 工程化的常见手法。

actionsFieldSchema定义了按钮/链接列表:

export const actionsFieldSchema = { label: 'Actions', name: 'actions', type: 'object', list: true, ui: { defaultItem: { label: 'Action Label', type: 'button', icon: true, link: '/' }, itemProps: (item: any) => ({ label: item.label }), }, fields: [ { label: 'Label', name: 'label', type: 'string' }, { label: 'Type', name: 'type', type: 'string', options: [ { label: 'Button', value: 'button' }, { label: 'Link', value: 'link' }, ], }, { label: 'Link', name: 'link', type: 'string' }, { label: 'Icon', name: 'icon', type: 'boolean' }, ], };

colorFieldSchema则把区块底色限定为default/tint/primary三个选项,保证视觉风格可控。shared-fields.ts还提供了makeSlugifytagsFieldSchemadateFieldSchemas等其他可复用片段,可整体作为团队级 schema 约定的参考范式。

从 Markdown 到页面:blocks 的渲染链路

理解了数据与 schema,再看前端如何把home.md变成真实页面。以 Next.js 版本为例,渲染链路分为两层:

第一层:数据获取与可视化订阅。examples/next/kitchen-sink/app/[...urlSegments]/client-page.tsx 是页面客户端组件,它接收服务端通过 Tina GraphQL 查询得到的query/variables/data,调用useTina完成内容订阅——编辑模式下数据变更会实时回流,构建模式下则直接使用静态数据:

const { data } = useTina({ ...props }); const page = data?.page; // ... <Blocks blocks={page.blocks} />

第二层:区块分发渲染。examples/next/kitchen-sink/components/blocks/index.tsx 中的Blocks组件遍历blocks数组,依据_template(或由__typename反查的模板名)通过switch分发到对应的动态导入组件:

const template = blockWithMeta._template || typeNameMap[typename] || typename; switch (template) { case 'hero': content = <Hero data={...} />; break; case 'features': content = <Features data={...} />; break; case 'cta': content = <CTA data={...} />; break; case 'testimonial': content = <Testimonial data={...} />; break; case 'content': content = <Content data={...} />; break; default: // 未知模板给出黄色告警占位 }

这里使用next/dynamic做按需加载,且保留了新旧两套__typename命名(PageBlocksHero与旧的PageBlockPageBlocksHero)的兼容映射,避免 schema 重新生成后破坏既有内容。遇到未知模板时渲染黄色告警占位,保证页面不会因数据异常而崩溃。

实操:如何扩展首页区块

基于以上机制,扩展现有首页有几种典型操作:

  1. 给 hero 增加按钮:在home.md的 heroactions列表追加一个条目,type可选buttonlinkicon控制是否显示箭头图标;也可以在 TinaCMS 后台表单中直接点击添加。
  2. 新增特性条目:在 features 的items下追加{ icon: {...}, title, text }icon.name填入图标库名称(如BiSearchAlt2BiLayerBiTerminal),icon.coloricon.style控制图标外观。
  3. 切换区块主题色:将任意区块的colordefault/tint/primary之间调整,即可改变该区块的视觉层次。
  4. 调整区块顺序:由于blocks是有序数组,调整数组元素顺序即改变页面区块的上下排列;后台编辑器中通过拖拽或上下移动也能完成同样操作。
  5. 新增模板类型:若需要全新区块,在templates中注册新的xxxBlockSchema,在 components/blocks/index.tsx 的typeNameMapswitch中补充分发逻辑,即可让该模板出现在后台的区块选择器与前端渲染中。

小结

home.md虽然只是一份十几行的 Markdown 文件,却是理解 TinaCMS 内容建模范式的浓缩样本:frontmatter 中的blocks数组与_template标记构成「数据即结构」的内容层,page.tsxcollection 完成 schema 契约的声明,各 block schema 与共享字段决定后台表单形态,而client-page.tsx+blocks/index.tsx完成从数据到组件的渲染闭环。这种「Git 仓库存内容、GraphQL 查内容、可视化编辑器改内容」的架构,正是 TinaCMS 面向 developer-first 站点的核心设计,也是你在自己的 Next.js / Astro / Hugo / React 项目中落地同类 CMS 方案的直接参考。

【免费下载链接】tinacmsTinaCMS is the leading open-source headless CMS that supports Markdown and Visual Editing. Your content is stored in your own GitHub repo 🦙 ❤️项目地址: https://gitcode.com/GitHub_Trending/ti/tinacms

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询