自定义主题 - moonlightL/hexo-boot GitHub Wiki
xxx
├─source # 目录,存放页面用到的css,javascript,font 等静态资源
├─about.html # 关于页面
├─archives.html # 归档页面
├─categories.html # 分类页面
├─detail.html # 文章详情页面
├─friendLinks.html # 友链页面
├─index.html # 首页页面
├─layout.html # 布局页面
├─postList.html # 分类,标签查询页面
├─preview.png # 预览图(1344x768 左右)
├─tags.html # 标签页面
├─theme.json # 主题配置文件
注意:主题目录名 xxx 为自定义名称
注意:主题目录下的文件以及文件夹名称皆为固定名称,不可改
注意:主题完成后,上传到 GitHub 或码云上,主题文件夹必须为 hexo-boot-theme-xxx 格式
全局变量存放在 servletContext 中,包含如下几个属性:
变量名 | 类型 | 描述 |
---|---|---|
configMap | Map | 博客基本属性集合 |
categoryList | List | 分类列表 |
friendLinkList | List | 友链列表 |
postNum | int | 文章数 |
categoryNum | int | 分类数 |
tagNum | int | 标签数 |
friendLinkNum | int | 友链数 |
(1)configMap 属性中包含的数据:
变量名 | 类型 | 描述 |
---|---|---|
install_time | String | 安装时间(yyyyMMdd HH:mm:ss) |
home_page | String | 博客地址 |
blog_name | String | 主题名称 |
description | String | 博客描述 |
keywords | String | 主题关键字 |
logo_url | String | logo 图片地址 |
favicon_url | String | favicon 图片地址 |
record | String | 网站备案号 |
power_by | String | 版权信息 |
blog_author | String | 博客作者 |
String | 邮箱地址 | |
git_hub_account | String | github 地址 |
wx_account | String | 微信名 |
qq_account | String | qq 号 |
wei_bo_account | String | 微博名 |
reward_comment | String | 打赏话语 |
reward_by_ali_pay | String | 支付宝收款码图片 |
reward_by_we_chat_pay | String | 微信收款码图片 |
页面模板采用 thymeleaf,因此使用全局变量方式如下:
# 返回博客名称
${#servletContext.getAttribute('configMap')['blog_name']}
(2)categoryList 属性中包含的数据:
变量名 | 类型 | 描述 |
---|---|---|
id | int | 分类id |
name | String | 分类名称 |
coverUrl | String | 分类封面地址 |
remark | String | 分类描述 |
postNum | int | 分类下的文章数量 |
# 返回分类列表
${#servletContext.getAttribute('categoryList ')}
(3)friendLinkList 属性中包含的数据:
变量名 | 类型 | 描述 |
---|---|---|
id | int | 友链id |
title | String | 友链标题 |
logo | String | 友链图片 |
author | String | 友链站长 |
homeUrl | string | 友链地址 |
linkType | int | 友链类型 1:博主主页 2:常用网址 |
backgroundColor | String | 背景颜色 |
remark | string | 友链描述 |
# 返回友链列表
${#servletContext.getAttribute('friendLinkList ')}
注意:任何页面都可访问全局变量!!!
当访问页面后,会额外提供以下变量:
变量名 | 类型 | 描述 |
---|---|---|
isDetail | Boolean | 是否为详情页 |
activeTheme | Theme | 当前主题对象 |
md | Object | markdown 工具类 |
countInfo | Map | 相关数量 |
activeTheme 中的属性如下:
变量名 | 类型 | 描述 |
---|---|---|
name | String | 主题名称 |
remark | String | 主题描述 |
configMap | Map | 主题扩展属性(文章末尾介绍) |
使用局部变量方式如下:
${isDetail}
布局页面名称为 layout.html,该页面也是模板页面,用于展示页面的公共部分。
下边列举 layout.html 大致内容:
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="width=device-width, initial-scale=1" name="viewport" />
<title th:text="${#servletContext.getAttribute('configMap')['blog_name']}">个人博客</title>
<meta name="author" th:content="${#servletContext.getAttribute('configMap')['blog_author']}">
<meta name="keywords" th:content="${#servletContext.getAttribute('configMap')['keywords']}" />
<meta name="description" th:content="${#servletContext.getAttribute('configMap')['description']}" />
<meta name="referrer" content="no-referrer" />
</head>
<!-- END HEAD -->
<body>
<div class="page-wrapper">
<!-- 导航,代码省略 -->
<!-- 内容 -->
<div layout:fragment="content" ></div>
<!-- 版权,联系方式,代码省略 -->
</div>
</body>
</html>
页面中展示大部分公共的页面信息,只有 <div layout:fragment="content" ></div>
部分为可变内容,需要结合其他页面展示。
其他页面的内容大致为:
<!doctype html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout" layout:decorate="~{theme/xxx/layout}">
<head>
<title th:text="${#servletContext.getAttribute('configMap')['blog_name']} + ' | 首页'"></title>
</head>
<body>
<div layout:fragment="content">
<!-- 具体内容,代码省略 -->
</div>
</body>
</html>
首页页面名称为 index.html,访问路径为 "/",用于展示文章列表。在此页面中,可访问特有的 pageInfo 变量。
pageInfo 变量中的属性
变量名 | 类型 | 描述 |
---|---|---|
data | List | 文章列表,List 封装 Post 类型 |
hasPreviousPage | Boolean | 是否有上一页 |
hasNextPage | Boolean | 是否有下一页 |
navigatepageNums | List | 页码数组 |
Post 变量中的属性
变量名 | 类型 | 描述 |
---|---|---|
title | String | 文章标题 |
summary | String | 文章摘要,存文本格式 |
summaryHtml | String | 文章标题,html 格式 |
link | String | 文章链接 |
coverUrl | String | 文章封面 |
categoryName | String | 文章分类 |
tags | String | 文章标签 |
publishDate | String | 发表日期 |
readNum | Integer | 浏览数 |
commentNum | Integer | 评论数 |
top | Boolean | 是否置顶 |
reprint | Boolean | 文章是否为转载 |
year | String | 年份 |
month | String | 月份 |
day | String | 日期 |
注意:该页面从第2页起,访问路径为 "/page/页码数/"
首页页面名称为 archives.html,访问路径为 "/archives/",用于展示文章列表。在此页面中,可访问特有的 pageInfo 变量。
pageInfo 变量中的属性
变量名 | 类型 | 描述 |
---|---|---|
data | Map | 文章数据,key 为年份(String),value 为文章列表(List,封装 Post) |
total | Integer | 文章总数 |
hasPreviousPage | Boolean | 是否有上一页 |
hasNextPage | Boolean | 是否有下一页 |
total | Integer | 文章总数 |
navigatepageNums | List | 页码数组 |
注意:该页面从第2页起,访问路径为 "/archives/页码数/"
分类页面名称为 categories.html,访问路径为 "/categories/",用于展示分类列表。在此页面中,可访问特有的 categoryList 和 count 变量。
categoryList 为 List 类型,其元素的属性如下:
变量名 | 类型 | 描述 |
---|---|---|
name | String | 分类名称 |
coverUrl | String | 分类封面 |
postNum | Integer | 分类下的文章数 |
分类页面名称为 tags.html,访问路径为 "/tags/",用于展示分类列表。在此页面中,可访问特有的 tagList 和 count 变量。
tagList为 List 类型,其元素的属性如下:
变量名 | 类型 | 描述 |
---|---|---|
name | String | 标签名称 |
分类页面名称为 friendLinks.html,访问路径为 "/friendLinks/",用于展示分类列表。在此页面中,可访问特有的 bloggerList 和 webSiteList 变量。
其中 bloggerList 表示博主网址,webSiteList 表示第三方工具等网址,它们都 List 类型,其元素的属性如下:
变量名 | 类型 | 描述 |
---|---|---|
backgroundColor | String | 背景颜色 |
title | String | 友链标题 |
homeUrl | String | 友链地址 |
remark | String | 友链备注 |
分类页面名称为 about.html,访问路径为 "/about/",用于展示分类列表。在此页面中,可访问特有的 about 变量。
通常页面内容如下:
<div id="postContainer" class="postContainer animated fadeInUp">
<div class="post-content" th:utext="${md.md2html(#objects.nullSafe(about.descr, '懒人一枚~~'))}"></div>
<div class="alert alert-info" role="alert">
<ul class="post-copyright">
<li>
<strong>本文作者:</strong> <b>[[${#servletContext.getAttribute('configMap')['blog_author']}]]</b>
</li>
<li>
<strong>本文链接:</strong> <a id="shareUrl" class="alert-link" th:href="@{${#servletContext.getAttribute('configMap')['home_page']} + '/about/'}" target="_blank" th:text="${#servletContext.getAttribute('configMap')['home_page']+'/about/'}"></a>
</li>
<li>
<strong>版权声明:</strong> 本博客所有文章除特别声明外均为原创,采用 <a th:href="@{${#servletContext.getAttribute('configMap')['license_url']}}" class="alert-link" target="_blank" th:text="${#servletContext.getAttribute('configMap')['license']}"></a> 许可协议。转载请在文章开头明显位置注明原文链接和作者等相关信息,明确指出修改(如有),并通过 E-mail 等方式告知,谢谢合作!
</li>
</ul>
</div>
</div>
详情页面名称为 detail.html,用于展示分类列表。在此页面中,可访问特有的 post 变量。
Post 变量中的属性
变量名 | 类型 | 描述 |
---|---|---|
title | String | 文章标题 |
link | String | 文章链接 |
content | String | 文章内容 |
categoryName | String | 文章分类 |
tags | String | 文章标签 |
publishDate | String | 发表日期 |
readNum | Integer | 浏览数 |
commentNum | Integer | 评论数 |
top | Boolean | 是否置顶 |
reprint | Boolean | 文章是否为转载 |
year | String | 年份 |
month | String | 月份 |
day | String | 日期 |
其中,content 为 markdown 内容,我们需要如下操作才能正常展示内容:
<div th:utext="${md.md2html(post.id, post.content, 2)}"></div>
详情页面名称为 postList.html,用于展示分类/标签列表。访问路径为 /categories/分类名/ 或 /tags/标签名/ 在此页面中,可访问特有的 pageInfo 变量 和 type 变量。
pageInfo 变量中的属性
变量名 | 类型 | 描述 |
---|---|---|
list | List | 文章列表,List 封装 Post 类型 |
total | Integer | 相关的文章数 |
hasPreviousPage | Boolean | 是否有上一页 |
hasNextPage | Boolean | 是否有下一页 |
navigatepageNums | List | 页码数组 |
Post 变量中的属性
变量名 | 类型 | 描述 |
---|---|---|
title | String | 文章标题 |
link | String | 文章链接 |
coverUrl | String | 文章封面 |
categoryName | String | 文章分类 |
tags | String | 文章标签 |
publishDate | String | 发表日期 |
readNum | Integer | 浏览数 |
commentNum | Integer | 评论数 |
top | Boolean | 是否置顶 |
reprint | Boolean | 文章是否为转载 |
year | String | 年份 |
month | String | 月份 |
day | String | 日期 |
注意:该页面从第2页起,访问路径为 "/categories/分类名/page/页码数/" 或 "/tags/标签名/page/页码数/"
主题配置文件名为 theme.json,以默认主题配置文件为例,内容如下:
{
"name": "default",
"remark": "默认主题",
"extension": [
{
"key": "pageSize",
"value": "10",
"type": "input",
"label": "页面大小"
},
{
"key": "commentShowType",
"value": "singleRow",
"type": "select",
"option": "singleRow,multiRow",
"label": "评论列表展示"
}
]
}
说明:
name: 主题名称
remark: 主题描述
extension:主题扩展属性
该内容基本固定,如有扩展属性,只需在 extension 下添加即可。
其中,key 表示属性名。value 表示属性值。type 表示输入形式(input:手写; select:选框,与 option 联合使用)。label 表示标签说明。
使用主题变量方式:${activeTheme.configMap['keyName']}
, keyName 就是上边定义的 key。