自定义主题 - 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 博客作者
email 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/",用于展示分类列表。在此页面中,可访问特有的 categoryListcount 变量。

categoryList 为 List 类型,其元素的属性如下:

变量名 类型 描述
name String 分类名称
coverUrl String 分类封面
postNum Integer 分类下的文章数

标签页面

分类页面名称为 tags.html,访问路径为 "/tags/",用于展示分类列表。在此页面中,可访问特有的 tagListcount 变量。

tagList为 List 类型,其元素的属性如下:

变量名 类型 描述
name String 标签名称

友链页面

分类页面名称为 friendLinks.html,访问路径为 "/friendLinks/",用于展示分类列表。在此页面中,可访问特有的 bloggerListwebSiteList 变量。

其中 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。

⚠️ **GitHub.com Fallback** ⚠️