深入解析 Vercel Eleventy 示例博客的文章组织:以 secondpost.md 为例
2026/9/23 22:47:22 网站建设 项目流程

深入解析 Vercel Eleventy 示例博客的文章组织:以 secondpost.md 为例

【免费下载链接】vercelDevelop. Preview. Ship.项目地址: https://gitcode.com/gh_mirrors/ve/vercel

本指南以当前仓库 examples/eleventy 示例站点中的博文 secondpost.md 为骨架,逐层拆解 Eleventy(11ty)静态博客在 Vercel 上的文章组织方式:从 Front Matter 元数据、内容集合(Collections)与标签分页,到 Nunjucks 布局模板的渲染链路。读完本文,你将掌握如何在 Vercel 零配置部署的 Eleventy 项目中编写、串联并发布一篇结构完整、带元数据与站内导航的博客文章。

一、secondpost.md 的整体结构

secondpost.md是 Eleventy 示例博客的一篇占位博文,位于 examples/eleventy/posts/secondpost.md,全文由两部分组成:

  1. Front Matter:文件顶部的 YAML 元数据块(以---包裹);
  2. Markdown 正文:包含普通段落、二级标题(## Section Header)以及两个指向其他文章的站内链接。

1. Front Matter 元数据块

--- title: This is my second post. description: This is a post on My Blog about leveraging agile frameworks. date: 2018-07-04 tags: - number 2 layout: layouts/post.njk ---

这段元数据定义了文章的五个核心属性,它们直接决定文章在站点中的呈现方式与归类方式:

字段值示例作用
titleThis is my second post.文章标题,被布局模板渲染为<h1>,也用于文章列表、归档页的标题展示
description一段英文描述文章摘要/描述,可用于 SEO 与 RSS/JSON Feed 输出
date2018-07-04文章发布日期,被post.njk布局格式化为<time>标签
tagsnumber 2文章标签,驱动标签页分页与文章归类
layoutlayouts/post.njk指定文章使用的布局模板,路径相对于_includes目录

从仓库中另外几篇博文(如 firstpost.md、thirdpost.md、fourthpost.md)可以看出,这套 Front Matter 是每篇文章的通用模板:firstpost.mdtagsanother tagthirdpost.md同时声明了second tagposts with two tags两个标签,而fourthpost.md使用 YAML 流式写法tags: second tag。这说明tags字段既支持列表形式也支持单值字符串形式,Eleventy 会将其归一化处理。

2. Markdown 正文与站内链接

正文部分包含普通段落、一个## Section Header二级标题,以及两个带 Nunjucks 模板语法的站内链接:

<a href="{{ '/posts/firstpost/' | url }}">First post</a> <a href="{{ '/posts/thirdpost/' | url }}">Third post</a>

这里使用了 Eleventy 内置的url过滤器(filter)。它负责将站点根路径(由_data/metadata.json中的url字段定义)与文章路径正确拼接,并自动处理路径前缀(如部署在子路径时)。这正是 Eleventy 中"内容与路径分离"的体现:文章作者只需写出逻辑路径/posts/firstpost/,具体的基础 URL 由构建配置决定。

二、集合(Collections)机制:文章如何被自动收集

secondpost.md中声明的tags并不只是展示标签,它同时把文章纳入了 Eleventy 的**内容集合(Collections)**体系。关键在于 posts/posts.json 这个目录级数据文件:

{ "tags": [ "posts" ] }

Eleventy 会为posts/目录下的所有文件自动合并该 JSON 中的 Front Matter 数据。因此,secondpost.md实际拥有两个标签:来自posts.jsonposts,以及来自自身 Front Matter 的number 2。前者是集合标记,后者是展示标签。这正是 Eleventy 官方推荐的"集合与展示标签分离"的实践——README.md中也明确指出:posts/目录中的文章只需要post标签即可被加入该集合(示例中集合名为posts)。

一旦文章被打上posts标签,它就会出现在collections.posts集合中,供模板遍历:

  • index.njk 首页通过collections.posts | head(-3)取最新 3 篇;
  • archive.njk 归档页(permalink: /posts/)遍历整个collections.posts输出全部文章;
  • tags.njk 标签页通过pagination.data: collections对每个标签生成/tags/{{ tag | slug }}/分页页面,并用filter排除allnavpostpoststagList等内部集合。

三、布局模板渲染链路:从 Markdown 到 HTML

secondpost.mdlayout: layouts/post.njk指向 examples/eleventy/_includes/layouts/post.njk。该模板是文章渲染的核心,其工作流程如下:

  1. 标题渲染<h1>{{ title }}</h1>输出 Front Matter 中的title
  2. 日期格式化<time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time>调用htmlDateStringreadableDate两个过滤器(由luxon日期库提供),输出标准datetime属性与人类可读日期;
  3. 标签循环tags | filterTagList过滤掉内部标签(如posts)后,为每个标签生成指向/tags/{{ tag | slug }}/的链接,slug过滤器把标签文本转为 URL 友好的 slug;
  4. 正文注入{{ content | safe }}把 Markdown 正文(含## Section Header与站内链接)经 markdown-it 解析后的 HTML 原样注入;
  5. 上一篇/下一篇导航:借助collections.posts | getNextCollectionItem(page)getPreviousCollectionItem(page)过滤器,自动生成文章间的 Next/Previous 导航。

布局是嵌套的:post.njk自身的 Front Matter 声明layout: layouts/base.njk,即文章模板会被包裹进 base.njk 提供的最外层 HTML 结构(<html><head>、导航等)。这与README.md中描述的"三层布局"体系一致:base.njk(顶层结构)→home.njk/post.njk(页面模板)→ 具体内容。

四、全局数据与站点元信息

文章中的description等字段可以与全局数据配合使用。站点的全局元信息定义在 _data/metadata.json:

{ "title": "Your Blog Name", "url": "https://example.com/", "language": "en", "description": "I am writing about my experiences as a naval navel-gazer.", "feed": { "subtitle": "I am writing about my experiences as a naval navel-gazer.", "filename": "feed.xml", "path": "/feed/feed.xml", "id": "https://example.com/" }, "jsonfeed": { "path": "/feed/feed.json", "url": "https://example.com/feed/feed.json" }, "author": { "name": "Your Name Here", "email": "youremailaddress@example.com", "url": "https://example.com/about-me/" } }

_data/目录下的 JSON 文件会自动注入到模板的全局数据命名空间(这里即metadata变量)。例如 feed/feed.njk 与feed/json.njk就引用metadata.feedmetadata.jsonfeedmetadata.author生成 RSS Feed 与 JSON Feed,这正是 README 中提到的"全局数据文件"用法。url字段同时被url过滤器用作路径基准——secondpost.md{{ '/posts/firstpost/' | url }}的最终输出地址正是基于该字段计算得出的。

五、构建命令与 Vercel 零配置部署

secondpost.md这样的文章从源码变为线上页面,构建过程由 examples/eleventy/package.json 中的 scripts 驱动:

"scripts": { "build": "eleventy", "watch": "eleventy --watch", "serve": "eleventy --serve", "start": "eleventy --serve", "debug": "DEBUG=* eleventy" }

README 中给出了完整的本地工作流:npm install安装依赖 → 编辑_data/metadata.json配置站点信息 → 使用npx eleventy执行构建,或通过npx eleventy --serve启动本地开发服务器、npx eleventy --watch在模板变更时自动重建、DEBUG=* npx eleventy进入调试模式。

该示例仓库被设计为可直接部署到 Vercel:README.md明确说明这是一个"zero configuration"(零配置)部署的 Eleventy 站点。Vercel 会自动检测到该项目的 Eleventy 构建配置(基于package.json中的build脚本与输出目录约定),执行构建后发布为静态站点;本地预览时--serve提供的开发服务器与线上产物行为一致。这也意味着:secondpost.md## Section Header这类 Markdown 结构、Nunjucks 链接与 Front Matter 元数据,在 Vercel 的构建环境中都会被 Eleventy 完整解析并输出为静态 HTML,无需额外的服务端运行时配置。

六、实战要点小结

  • 写新文章:在 examples/eleventy/posts 目录下新建.md文件,复制secondpost.md的 Front Matter 骨架,填写titledescriptiondatetagslayout
  • 进入归档:文章无需手动登记,只要它位于posts/目录(经 posts.json 自动获得posts标签),就会自动出现在 index.njk 首页、archive.njk 归档页和 tags.njk 标签页中;
  • 站内互链:使用{{ '/posts/xxx/' | url }}形式生成带基础路径前缀的链接,而不是硬编码绝对 URL;
  • 文章导航:上一篇/下一篇由post.njk布局基于collections.posts自动生成,无需手写;
  • 上线npx eleventy本地验证构建产物后,推送到 Git 仓库即可由 Vercel 零配置完成构建与发布。

【免费下载链接】vercelDevelop. Preview. Ship.项目地址: https://gitcode.com/gh_mirrors/ve/vercel

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

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

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

立即咨询