在 Hexo 主题开发中,变量是连接数据与模板的桥梁。你可以把变量想象成“快递包裹”,Hexo 引擎在渲染页面时,会将文章内容、站点配置、日期信息等打包进不同的变量对象中,模板只需拆开对应的包裹即可获取内容。如果不知道这些变量的存在,你就无法在页面上动态展示文章标题、分类列表或分页导航。
全局变量:模板中的通用工具箱
无论当前渲染的是首页、文章页还是归档页,以下全局变量始终可用。它们是访问站点核心数据的入口。
| 变量 | 描述 | 类型 | 比喻 |
|---|---|---|---|
site |
全站信息集合 | Object | “图书馆总目录”,包含所有书籍(文章)和索引(分类/标签)。 |
page |
当前页面专属数据 | Object | “当前阅读的这本书”,包含这一页的标题、内容、自定义属性等。 |
config |
站点配置文件 (_config.yml) |
Object | “建站说明书”,包含站点标题、URL、部署设置等全局设定。 |
theme |
主题配置文件 | Object | “装修手册”,继承自站点配置,但包含主题特有的开关和设置。 |
path |
当前页面路径(不含根路径) | String | “房间号”,如 about/index.html。 |
url |
当前页面完整网址 | String | “完整门牌地址”,包含域名和路径。 |
env |
环境变量 | 未知 | “施工环境标识”,用于判断是开发环境还是生产环境。 |
重要变更说明:
从 Hexo 5.0.0 开始,Lodash 库已从全局变量中移除。如果你在旧主题中看到 _ (代表 Lodash) 的直接调用,迁移时需要手动引入或使用原生 JavaScript 方法替代。参考资源 You-Dont-Need-Lodash-Underscore 可协助你找到原生替代方案。
网站变量 (site):全站数据概览
通过 site 对象,你可以访问博客的所有内容,常用于生成侧边栏的“最新文章”、“热门标签”或“归档列表”。
site.posts: 所有文章的数组。按时间倒序排列,包含站点全部的文章对象。site.pages: 所有独立分页(如“关于我”、“友情链接”)的数组。site.categories: 所有分类的 Query 对象。可用于遍历生成分类云。site.tags: 所有标签的 Query 对象。可用于遍历生成标签云。
使用示例:
1 | <!-- 列出所有分类 --> |
页面变量 (page):当前内容详情
page 对象的内容会根据当前渲染的页面类型(文章、首页、分类页等)动态变化。它是模板中最常用的变量。
1. 通用页面变量 (适用于所有页面)
| 变量 | 描述 | 类型 |
|---|---|---|
page.title |
文章或页面标题 | String |
page.date |
创建日期 (Moment.js 对象) | Object |
page.updated |
更新日期 (Moment.js 对象) | Object |
page.comments |
是否启用评论 | Boolean |
page.layout |
使用的布局名称 | String |
page.content |
渲染后的完整 HTML 内容 | String |
page.excerpt |
文章摘要 (通常指 <!-- more --> 之前的内容) |
String |
page.more |
摘要之后的剩余内容 | String |
page.source |
源文件相对路径 | String |
page.full_source |
源文件绝对路径 | String |
page.path |
页面生成路径 (建议配合 url_for() 使用) |
String |
page.permalink |
文章的完整永久链接 | String |
page.prev / page.next |
上一篇/下一篇文章对象 (若无则为 null) | Object/Null |
page.raw |
文章原始 Markdown 内容 (未渲染) | String |
page.photos |
文章配图数组 (用于相册功能) | Array |
page.link |
外部链接地址 (用于“链接文章”格式) | String |
2. 文章页特有变量 (post 布局)
除了上述通用变量外,文章页还额外包含:
page.published: 布尔值。如果不是草稿,则为true。page.categories: 当前文章所属的分类数组。page.tags: 当前文章所属的标签数组。
概念辨析:page.path vs page.permalink
page.path: 只是文件生成的相对路径(例如2023/01/01/hello/index.html)。它不包含域名,且未经过 URL 编码处理。在模板中生成内部链接时,通常需要使用url_for(page.path)将其转换为完整的相对 URL。page.permalink: 已经是完整的、经过编码的绝对 URL(例如https://example.com/2023/01/01/hello/)。适合用于 SEO 标签(如canonical)或分享给外部用户。
3. 首页特有变量 (index 布局)
首页涉及分页逻辑,因此包含以下 paginator 相关变量:
| 变量 | 描述 | 类型 | 示例/备注 |
|---|---|---|---|
page.per_page |
每页显示的文章数 | Number | 如 10 |
page.total |
总页数 | Number | 如 5 |
page.current |
当前页码 | Number | 如 2 |
page.current_url |
当前分页的完整 URL | String | |
page.posts |
本页包含的文章列表 (Data Model) | Object | 仅包含当前页的 10 篇,而非全站 |
page.prev |
上一页页码 | Number | 第一页时为 0 |
page.prev_link |
上一页 URL | String | 第一页时为空字符串 '' |
page.next |
下一页页码 | Number | 最后一页时为 0 |
page.next_link |
下一页 URL | String | 最后一页时为空字符串 '' |
page.path |
当前页面的路径(不含根目录) | String | 同通用变量 |
命令与参数逻辑示例(分页判断):
在模板中实现“上一页”按钮时,不能直接输出链接,需先判断是否存在上一页。
1 | <% if (page.prev) { %> |
4. 分类、标签与归档页特有变量
这些页面本质上也是列表页,因此继承了 index 的所有变量,并增加了标识当前归档维度的变量。注意:素材中对于分类、标签和归档页的特定变量定义存在特殊的对应关系,请严格遵循以下说明。
分类页 (
category):- 继承
index布局变量。 - 新增变量:
page.archive: 恒为true(Boolean)。page.year: 年份归档 (4位数字)。page.month: 月份归档 (没有前导零的2位数)。
- 注意: 根据提供的素材表格,这些时间归档变量被列在“分类 (category)”部分下。
- 继承
标签页 (
tag):- 继承
index布局变量。 - 新增变量:
page.category: 分类名称 (String)。
- 注意: 根据提供的素材表格,获取分类名称的变量被列在“标签 (tag)”部分下。
- 继承
归档页 (
archive):- 继承
index布局变量。 - 新增变量:
page.tag: 标签名称 (String)。
- 注意: 根据提供的素材表格,获取标签名称的变量被列在“归档 (archive)”部分下。
- 继承
概念辨析:易混淆的变量归属
在标准的 Hexo 逻辑或直觉中,我们通常认为 page.category 属于分类页,page.tag 属于标签页。然而,依据本素材内容,变量的归属如下特殊对应:
- 分类页 拥有时间维度变量 (
year,month) 和archive标记。 - 标签页 拥有
page.category(分类名称) 变量。 - 归档页 拥有
page.tag(标签名称) 变量。
这种分配方式可能源于特定的主题结构或素材的特定上下文。在编写模板时,请务必根据当前页面的实际类型(通过 page.layout 或其他特征判断)来调用正确的变量,避免张冠李戴。例如,如果你在一个标签页模板中想要显示该标签所属的分类(如果业务逻辑支持),应使用 page.category;如果你在归档页需要显示相关标签,应使用 page.tag。
补充说明:
page.date和page.updated是 Moment.js 对象,你可以直接调用.format('YYYY-MM-DD')等方法来格式化日期。- 在使用
page.prev、page.next或分页链接时,务必先进行if判断,防止在第一页或最后一页时因访问空值而报错。 - 若需调试页面变量,可在模板中临时输出
<%= JSON.stringify(page) %>以查看当前页面所有可用数据。