
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/tinacmshome.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-sink、examples/astro/kitchen-sink、examples/hugo/kitchen-sink、examples/react/kitchen-sink等示例工程均未自带content/pages目录而是统一复用examples/shared/content下的内容再分别用 Next.js、Astro、Hugo、React 等不同技术栈渲染同一份数据这本身就是 TinaCMS「内容与展示解耦」理念的直观体现。home.md全文是一个标准的 Markdown frontmatter 文件---之间只有blocks一个顶层键其值为一个有序数组依次声明了 4 个区块hero首屏横幅features特性列表cta行动号召testimonial用户引语每个区块对象都带有一个_template字段用于指定它属于哪种模板类型——这正是 TinaCMS 的「blocks 模板系统」在数据层的落点内容文件中只存结构化数据区块的类型与字段结构由_template声明而字段如何渲染则由前端组件决定。认识 page collectionblocks 字段如何被建模要让上述 Markdown 数据在 TinaCMS 后台可编辑必须先有对应的 collection 定义。kitchen-sink 示例的 page collection 位于 examples/next/kitchen-sink/tina/collections/page.tsxconst 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: objectlist: 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副文案渲染为富文本Markdownimageobject可选图片对象srcalt未设置则不渲染backgroundImageimage可选背景图accept: pngactionsobject list按钮/链接列表详见下文共享字段colorstring区块主题色default/tint/primaryhero.tsx中还给出了模板的defaultItem编辑器新增区块时的预填内容且ui.previewSrc: /blocks/hero.png指定了后台的区块预览缩略图——这正是 examples/shared/public/blocks/hero.png 的用途。从渲染组件看text字段通过TinaMarkdown渲染并支持自定义 Markdown 组件customComponentsactions则交由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 的featureBlockSchematitle/description区块标题与描述描述使用textarea组件itemslist: true的对象数组每个条目包含icon复用iconSchema配置name图标名、color主题色、style样式如circle、title、text、actionsui.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: ctacta 模板examples/next/kitchen-sink/components/blocks/cta.tsx的数据结构最为精简titledescriptionactionscolor。渲染时标题居中、描述跟随、动作按钮以Actions组件渲染。这个区块常被用作落地页的转化收尾区域color: tint让它在页面中呈现与 herodefault不同的底色层次。testimonial用户引语- quote: There are only two hard things in Computer Science: cache invalidation and naming things. author: Phil Karlton color: primary _template: testimonialtestimonial 模板examples/next/kitchen-sink/components/blocks/testimonial.tsx由quotetextarea、author、color三个字段构成渲染为带装饰性引号的大号块引用blockquotecolor: primary时使用高对比的主题色背景。有趣的是该模板 schema 中的defaultItem恰好就是 home.md 里这条著名的 Phil Karlton 语录说明这段示例内容正是从模板默认项沿用而来的。共享字段actions 与 color 的复用设计四个区块反复出现actions与color两个字段它们不是各自复制粘贴而是抽取自 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还提供了makeSlugify、tagsFieldSchema、dateFieldSchemas等其他可复用片段可整体作为团队级 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 重新生成后破坏既有内容。遇到未知模板时渲染黄色告警占位保证页面不会因数据异常而崩溃。实操如何扩展首页区块基于以上机制扩展现有首页有几种典型操作给 hero 增加按钮在home.md的 heroactions列表追加一个条目type可选button或linkicon控制是否显示箭头图标也可以在 TinaCMS 后台表单中直接点击添加。新增特性条目在 features 的items下追加{ icon: {...}, title, text }icon.name填入图标库名称如BiSearchAlt2、BiLayer、BiTerminalicon.color与icon.style控制图标外观。切换区块主题色将任意区块的color在default/tint/primary之间调整即可改变该区块的视觉层次。调整区块顺序由于blocks是有序数组调整数组元素顺序即改变页面区块的上下排列后台编辑器中通过拖拽或上下移动也能完成同样操作。新增模板类型若需要全新区块在templates中注册新的xxxBlockSchema在 components/blocks/index.tsx 的typeNameMap与switch中补充分发逻辑即可让该模板出现在后台的区块选择器与前端渲染中。小结home.md虽然只是一份十几行的 Markdown 文件却是理解 TinaCMS 内容建模范式的浓缩样本frontmatter 中的blocks数组与_template标记构成「数据即结构」的内容层page.tsxcollection 完成 schema 契约的声明各 block schema 与共享字段决定后台表单形态而client-page.tsxblocks/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),仅供参考