第4章:Front Matter 详解
第4章:Front Matter 详解
4.1 什么是 Front Matter
Front Matter(前置数据)是 Jekyll 文件开头的 YAML 块,用于为页面和文章提供元数据。它是 Jekyll 处理文件的触发条件——只有包含 Front Matter 的文件才会被 Jekyll 处理。
基本语法
---
title: "我的文章"
date: 2025-01-15
layout: post
---
三横线 --- 标记 Front Matter 的开始和结束,中间是 YAML 格式的键值对。
触发规则
| 文件情况 | Jekyll 是否处理 | 说明 |
|---|---|---|
| 有 Front Matter | ✅ 处理 | 解析 Liquid、Markdown → HTML |
| 无 Front Matter | ❌ 不处理 | 直接复制到 _site/(仅限静态文件) |
| 空 Front Matter | ✅ 处理 | ---\n--- 也算有效 |
---
---
# 这个文件也会被 Jekyll 处理
即使 Front Matter 为空
注意事项:如果你的 .md 或 .html 文件没有被 Jekyll 渲染,首先检查是否遗漏了 Front Matter。
4.2 预定义变量
Jekyll 内置了一系列预定义的 Front Matter 变量。
核心预定义变量
| 变量 | 类型 | 说明 | 示例 |
|---|---|---|---|
layout | String | 使用的布局模板 | "post" |
title | String | 页面/文章标题 | "Jekyll 入门" |
date | DateTime | 发布日期 | 2025-01-15 10:30:00 |
published | Boolean | 是否发布(设为 false 则不生成) | true |
permalink | String | 自定义 URL | "/my-page/" |
categories | String/List | 分类 | ["ruby", "web"] |
tags | List | 标签 | ["tutorial", "beginner"] |
description | String | 页面描述(SEO) | "文章简介" |
excerpt | String | 自定义摘要 | "这是摘要..." |
comments | Boolean | 是否启用评论 | true |
slug | String | URL 中的文件名部分 | 自动从文件名提取 |
ext | String | 文件扩展名 | .md |
draft | Boolean | 是否为草稿 | true |
layout 变量
# 使用 _layouts/post.html
layout: post
# 使用 _layouts/page.html
layout: page
# 不使用布局(纯内容输出)
layout: null
# 嵌套布局(见第6章)
layout: default
date 变量
# 精确到秒
date: 2025-01-15 10:30:00 +0800
# 仅日期
date: 2025-01-15
# ISO 8601 格式
date: 2025-01-15T10:30:00+08:00
# 注意:文件名中的日期会作为默认值
# 文件:2025-01-15-my-post.md
# 如果 Front Matter 中没有 date,使用文件名中的 2025-01-15
categories 变量
# 单分类
categories: ruby
# 多分类(字符串方式,空格分隔)
categories: ruby web jekyll
# 多分类(列表方式,推荐)
categories:
- ruby
- web
- jekyll
# 分类会反映在 URL 中
# permalink: /:categories/:year/:month/:day/:title/
# 输出: /ruby/web/2025/01/15/my-post/
tags 变量
# 标签列表
tags:
- tutorial
- beginner
- jekyll
# 行内写法
tags: [tutorial, beginner, jekyll]
categories 与 tags 的区别:
- Categories(分类)是层级化的,可以嵌套:
/category/subcategory/ - Tags(标签)是扁平化的,没有层级关系
- Categories 影响 URL 结构,Tags 不影响
4.3 自定义变量
你可以在 Front Matter 中定义任意自定义变量,在模板中通过 page.变量名 访问。
常见自定义变量
---
title: "深入理解 Jekyll"
date: 2025-01-15
layout: post
# 自定义变量
author: "张三"
author_email: "[email protected]"
thumbnail: "/images/jekyll-thumb.jpg"
reading_time: "8 min"
difficulty: "intermediate"
series: "Jekyll 完全指南"
series_number: 4
license: "CC BY-NC 4.0"
last_modified_at: 2025-02-01
math: true # 启用数学公式
mermaid: true # 启用 Mermaid 图表
toc: true # 启用目录
---
在模板中使用自定义变量
<!-- _layouts/post.html -->
<article>
<h1>{{ page.title }}</h1>
<div class="meta">
<span class="author">{{ page.author }}</span>
<span class="reading-time">阅读时间:{{ page.reading_time }}</span>
{% if page.difficulty %}
<span class="badge {{ page.difficulty }}">{{ page.difficulty }}</span>
{% endif %}
</div>
{% if page.thumbnail %}
<img src="{{ page.thumbnail | relative_url }}" alt="{{ page.title }}">
{% endif %}
{% if page.toc %}
<nav class="toc">{{ content | toc_only }}</nav>
{% endif %}
<div class="content">
{{ content }}
</div>
{% if page.series %}
<div class="series-nav">
<h3>系列:{{ page.series }}</h3>
<p>第 {{ page.series_number }} 篇</p>
</div>
{% endif %}
</article>
访问自定义变量的完整路径
<!-- 在文章/页面模板中 -->
{{ page.author }}
<!-- 在 _includes/ 中通过 include 传递 -->
{% include author-info.html author=page.author %}
<!-- 在 _data/ 循环中 -->
{% for post in site.posts %}
{{ post.author }}
{% endfor %}
4.4 特殊用途的 Front Matter 变量
published: false
---
title: "未发布的文章"
published: false
---
# 这篇文章不会出现在 _site/ 中
# 也不会出现在 site.posts 中
# 区别于 draft:published 可以放在 _posts/ 中
permalink
# 文章级别永久链接
---
title: "关于我"
permalink: /about/
---
# 输出:_site/about/index.html
# 无论源文件在哪里
# 覆盖 _config.yml 的全局设置
permalink: /blog/:title/
redirect_from / redirect_to
# 需要 jekyll-redirect-from 插件
---
title: "我的文章"
redirect_from:
- /old-url/
- /another-old-url/
redirect_to: /new-page/ # 整个页面重定向到其他地址
---
sitemap
---
# 控制是否包含在 sitemap.xml 中(需 jekyll-sitemap 插件)
sitemap: false # 排除此页面
---
nav_order / weight
---
# 用于排序(取决于主题实现)
nav_order: 3 # 导航菜单排序
weight: 10 # 列表排序权重
---
4.5 Front Matter 默认值(Defaults)
在 _config.yml 中配置默认值,避免在每个文件中重复声明。
基本配置
# _config.yml
defaults:
# 为所有 posts 设置默认值
- scope:
path: ""
type: "posts"
values:
layout: "post"
author: "Site Admin"
comments: true
toc: true
# 为所有 pages 设置默认值
- scope:
path: ""
type: "pages"
values:
layout: "page"
author: "Site Admin"
# 为特定路径设置默认值
- scope:
path: "docs"
type: "pages"
values:
layout: "docs"
sidebar: true
# 为特定文件设置默认值
- scope:
path: "about/index.html"
values:
layout: "about-page"
scope 的匹配规则
| scope 字段 | 说明 | 示例 |
|---|---|---|
path | 文件路径前缀 | ""(全部)、"docs"、"docs/api" |
type | 内容类型 | "posts"、"pages"、"projects"(集合名) |
优先级规则
文件的 Front Matter > _config.yml defaults > 主题默认值
# _config.yml defaults
defaults:
- scope:
type: "posts"
values:
layout: "post"
author: "Default Author"
# _posts/2025-01-15-my-post.md
---
title: "My Post"
author: "Zhang San" # 覆盖默认值
# layout: "post" # 使用默认值
---
注意事项:
- Front Matter 中显式设置的值始终优先于 defaults
path匹配是前缀匹配:"docs"会匹配"docs/api/guide.md"type可以是"posts"、"pages"或集合名称
4.6 全局 Front Matter
通过 jekyll-default-front-matter 插件可以为新文件自动添加 Front Matter。
方法一:使用插件
# Gemfile
gem "jekyll-default-front-matter"
# _config.yml
plugins:
- jekyll-default-front-matter
default_front_matter:
"*.md":
author: "Admin"
comments: true
"_posts/*":
layout: "post"
tags: []
方法二:编辑器模板
# VS Code 设置(settings.json)
"files.associations": {
"*.md": "markdown"
},
"editor.snippets": {
"markdown": {
"New Jekyll Post": {
"prefix": "jpost",
"body": [
"---",
"title: \"$1\"",
"date: $CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE",
"layout: post",
"categories: [$2]",
"tags: [$3]",
"description: \"$4\"",
"---",
"",
"# $1",
"",
"$0"
]
}
}
}
方法三:自定义 Rake 任务
# Rakefile
desc "Create a new post"
task :post, [:title] do |t, args|
title = args[:title] || "New Post"
slug = title.downcase.gsub(/\s+/, '-').gsub(/[^\w-]/, '')
date = Time.now.strftime("%Y-%m-%d")
filename = "_posts/#{date}-#{slug}.md"
File.open(filename, 'w') do |f|
f.puts "---"
f.puts "title: \"#{title}\""
f.puts "date: #{Time.now.strftime("%Y-%m-%d %H:%M:%S %z")}"
f.puts "layout: post"
f.puts "categories: []"
f.puts "tags: []"
f.puts "description: \"\""
f.puts "---"
f.puts ""
f.puts "# #{title}"
f.puts ""
end
puts "Created #{filename}"
end
# 使用 Rake 创建新文章
rake post["Jekyll Front Matter 详解"]
4.7 Front Matter 数据类型
---
# 字符串
title: "Hello World"
# 也可以不加引号
title: Hello World
# 多行字符串
description: >
This is a very long
description that spans
multiple lines.
# 数字
reading_time: 8
priority: 1
# 布尔值
published: true
draft: false
comments: true
# 列表
tags: [jekyll, ruby, tutorial]
# 或
tags:
- jekyll
- ruby
- tutorial
# 日期
date: 2025-01-15 10:30:00 +0800
last_modified_at: 2025-02-01
# 嵌套对象
meta:
description: "SEO description"
keywords: [jekyll, static site]
og_image: "/images/social.png"
# 键值对映射
social_links:
github: "https://github.com/username"
twitter: "https://twitter.com/username"
---
4.8 Liquid 中访问 Front Matter
<!-- 访问当前页面的变量 -->
{{ page.title }}
{{ page.date | date: "%Y-%m-%d" }}
{{ page.author }}
{{ page.tags | join: ", " }}
<!-- 访问嵌套对象 -->
{{ page.meta.description }}
{{ page.social_links.github }}
<!-- 访问全局 site 配置 -->
{{ site.title }}
{{ site.description }}
<!-- 条件判断 -->
{% if page.toc %}
<nav class="toc">...</nav>
{% endif %}
{% if page.math %}
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
{% endif %}
4.9 业务场景:多作者博客
# _config.yml
defaults:
- scope:
type: "posts"
values:
layout: "post"
show_author: true
# _data/authors.yml
zhangsan:
name: "张三"
avatar: "/images/avatars/zhangsan.jpg"
bio: "全栈开发者,关注 Web 技术"
social:
github: "zhangsan"
twitter: "zhangsan_dev"
lisi:
name: "李四"
avatar: "/images/avatars/lisi.jpg"
bio: "DevOps 工程师"
# _posts/2025-01-15-jekyll-guide.md
---
title: "Jekyll 入门指南"
author: "zhangsan"
---
<!-- _includes/author-box.html -->
{% assign author = site.data.authors[page.author] %}
{% if author %}
<div class="author-box">
<img src="{{ author.avatar | relative_url }}" alt="{{ author.name }}">
<div>
<strong>{{ author.name }}</strong>
<p>{{ author.bio }}</p>
</div>
</div>
{% endif %}
4.10 扩展阅读
本章小结
| 要点 | 说明 |
|---|---|
| Front Matter 是触发器 | 有 Front Matter 的文件才会被 Jekyll 处理 |
| 预定义变量 | layout、title、date、categories、tags 等 |
| 自定义变量 | 任意键值对,通过 page.变量名 访问 |
| 默认值 | _config.yml 的 defaults 配置,减少重复 |
| 优先级 | 文件 Front Matter > defaults > 主题默认 |
下一章:Liquid 模板语言