深入解析 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,全文由两部分组成:
- Front Matter:文件顶部的 YAML 元数据块(以
---包裹); - 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 ---这段元数据定义了文章的五个核心属性,它们直接决定文章在站点中的呈现方式与归类方式:
| 字段 | 值示例 | 作用 |
|---|---|---|
title | This is my second post. | 文章标题,被布局模板渲染为<h1>,也用于文章列表、归档页的标题展示 |
description | 一段英文描述 | 文章摘要/描述,可用于 SEO 与 RSS/JSON Feed 输出 |
date | 2018-07-04 | 文章发布日期,被post.njk布局格式化为<time>标签 |
tags | number 2 | 文章标签,驱动标签页分页与文章归类 |
layout | layouts/post.njk | 指定文章使用的布局模板,路径相对于_includes目录 |
从仓库中另外几篇博文(如 firstpost.md、thirdpost.md、fourthpost.md)可以看出,这套 Front Matter 是每篇文章的通用模板:firstpost.md的tags为another tag,thirdpost.md同时声明了second tag与posts 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.json的posts,以及来自自身 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排除all、nav、post、posts、tagList等内部集合。
三、布局模板渲染链路:从 Markdown 到 HTML
secondpost.md的layout: layouts/post.njk指向 examples/eleventy/_includes/layouts/post.njk。该模板是文章渲染的核心,其工作流程如下:
- 标题渲染:
<h1>{{ title }}</h1>输出 Front Matter 中的title; - 日期格式化:
<time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time>调用htmlDateString与readableDate两个过滤器(由luxon日期库提供),输出标准datetime属性与人类可读日期; - 标签循环:
tags | filterTagList过滤掉内部标签(如posts)后,为每个标签生成指向/tags/{{ tag | slug }}/的链接,slug过滤器把标签文本转为 URL 友好的 slug; - 正文注入:
{{ content | safe }}把 Markdown 正文(含## Section Header与站内链接)经 markdown-it 解析后的 HTML 原样注入; - 上一篇/下一篇导航:借助
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.feed、metadata.jsonfeed与metadata.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 骨架,填写title、description、date、tags与layout; - 进入归档:文章无需手动登记,只要它位于
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),仅供参考