Hexo 自定义页面
先前使用的Hexo主题略显花哨,为了让博客更学术范一点,准备在2024年伊始换一个新的主题。这个过程中遇到不少问题,其中之一便是如何在Hexo中自定义页面。
目录
前言
与Hexo的邂逅已有5年之久,期间换过不少主题。虽然总会遇到一些问题,但大多都在Github的教程以及各种issue的帮助下迎刃而解。每当看到一个焕然一新的主题,心中不免会产生一丝成就感。但说来惭愧,这么多年一直都对Hexo的配置浅尝辄止,就连最核心的页面生成过程也是一知半解。
本次换了一个全新的主题——tranquilpeak。这个主题的UI风格很对我的胃口,美中不足的是它支持的特性并不是很丰富。例如,它不支持添加友情链接。本着不想抛弃那为数不多的“友谊”,我决定自己添加一个“友链”页面。
Hexo的渲染逻辑
Hexo框架
众所周知,Hexo是典型的静态博客框架。它需要用户先将本地的Markdown文件转化为静态的HTML网页,然后部署到服务器上以供他人访问。在实际访问过程中,服务器只需要负责返回一个个静态的网页即可,并不需要进行额外的存储和逻辑运算。
因此,如何根据用户编写的Markdown文档生成精致的HTML页面是Hexo需要解决的关键问题。Hexo网站内容的生成过程主要涉及三个核心部分:
- Hexo渲染引擎:这是Hexo框架的核心。它在主题的指示下,负责将Markdown文件转换为静态的HTML页面。
- Markdown数据:用户编写的博客内容。
- UI:Hexo的各种第三方主题。
一句话总结三者的关系就是:渲染引擎根据主题设定的UI样式将用户编写的Markdown文档渲染成HTML页面(包括html、css和js三件套)。
目录结构
接下来,我将根据Hexo项目的目录结构对Hexo页面的生成过程进行详细的介绍。一般而言,Hexo项目的目录主要包含以下内容:
1 | . |
渲染过程
_config.yml
:Hexo的配置文件。public
:存放Hexo生成得到的网页文件。部署时只需要将该目录上传到服务器,用户在浏览器端访问的也是public
中的文件。source
:存放用户数据,如用户创建的Markdown文档。themes
:存放若干个Hexo主题。languages
:国际化,用于多语言配置,里面定义了配置文件中变量到具体语言的映射。layout
:用于存放主题的模板文件,决定了网站内容的呈现方式。scripts
:script源码。source
:资源文件夹,存放除了模板以外的CSS、JavaScript文件等。_config.yml
:相应主题的配置文件。
主页面的生成
Hexo的页面布局主要由layout/layout.ejs
控制,每个模板都默认使用layout布局。具体而言,layout.ejs
通过body
变量将模板内容添加到生成文件的指定位置,例如:
1 | <!-- layout.ejs --> |
1 | <!-- index.ejs --> |
经过Hexo引擎处理,会在public
文件夹中生成一个index.html
文件,其内容为:
1 | <!-- public/index.html --> |
通过访问http://your-site/
,浏览器就会加载public/index.html
文件。
更多详细内容可参考Hexo-Templates。
其他页面的生成
上面展示了网站主页(index.html)的生成过程,其他页面的生成也是大同小异。例如,我们希望新建一个分类页面,来展示所有的分类项。
1、首先,需要在用户数据文件夹(source)为分类页面新建一个index.md
文件。下面这个命令会在source文件夹下新建一个category/index.md
文件。
1 | hexo new page category |
2、为分类页面新建一个布局文件,即themes/demo_theme/layout/category.ejs
。
1 | <!-- category.ejs --> |
3、将分类页面与相应的布局文件进行关联,这一过程只需要在category/index.md
的Front-matter中指定布局即可。
1 | --- |
layout: category
指代的便是layout/category.ejs
文件。这样Hexo引擎就知道需要根据指定的布局处理该Markdown文件。
值得注意的是,分类模板生成的内容同样需要经过layout/layout.ejs
,即替换其中的<%- body %>
。
所以,最终分类页面会得到以下内容:
1 | <!-- public/category/index.html --> |
该页面可以通过http://your-site/category/
访问。
自定义“友链”页面
回归到本文的主线任务,为博客自定义一个“友链”页面,用来展示他人网站的链接等。其原理与分类页面的创建相同,只需要将上述的category
替换为friends
即可。
得到的文件内容如下:
1 | <!-- public/friends/index.html --> |
当然,这仅仅是一个“友链”页面的演示,并没有将实际的数据渲染到该页面。下面,我们需要加载数据来充实该页面。
“友链”信息是相对规则的数据,通常包含他人网站的标题、简介、链接和favicon等。因此,我们可以将这些数据都存放到一个特定的json文件中,然后在friends.ejs
中读取并展示数据。
1、需要借助Hexo的数据文件(Data Files)。具体而言,在source文件下新建一个文件——_data/friends.json
,并添加需要的“友链”数据。
1 | [{ |
2、修改friends.ejs
文件,读取_data/friends.json
文件。
1 | <div> |
简洁起见,上述ejs代码仅仅读取了json数据,并进行了展示,没有添加任何css样式。代码中,涉及Hexo定义的一些变量(Variables),这里稍作解释。
page
: 全局变量,针对该页面的内容以及front-matter中定义的变量,如page.title
。site
: 全局变量site.posts
: 包含了站点全部的文章对象。site.categories
: 包含了站点全部的分类对象。site.tags
: 包含了站点全部的标签对象。site.data
: 包含了站点全部的数据文件对象。