hexo-liushen-themesliushen的博客中看着很不错,之前我就一直想用这个主题,但是当时不太懂这些,就放弃了,最近想起来想要折腾一下,所以直到现在才发现,仓库内的主题貌似是半成品

配置文件的修改

先参考butterfly的官方文档和liushen的仓库的 README.md 修改好配置文件

右侧栏

关于“欢迎来访者!”栏目

右侧栏中的字段被硬编码在themes\liushen\layout\includes\widget\card_welcome.pug

如果不想显示获取失败的面板,直接删掉那部分代码(#welcome-info)即可

右侧欢迎面板: others.js 修改

themes\liushen\source\js\others.js中的第261行有一段代码需要修改,源代码片段如下

1
return fetch('https://api.76.al/api/ip/query?key=这里要自己改改')

由于api.76.al已经无法访问,这里列出几个可用的api:

  • http://ip-api.com/json/?fields=country,regionName,city,zip,lat,lon,query&lang=zh-CN(因浏览器限制,此api仅限http网站可用)
  • https://whois.pconline.com.cn/ipJson.jsp?ip=&json=true(此api不会返回经纬度信息,需要修改经纬度判断逻辑)
  • https://api.nsuuu.com/(来自LiuShen推荐)

更多请参考 ip-info-api

同时如果需要使用其他的api(包含上方推荐的api),需要修改位于others.js中的如下代码:

  • 修改请求地址 (fetchIpLocation 函数)
  • 修改字段取值 (showWelcome 函数)

右键菜单

右键菜单存放于themes\liushen\layout\includes\rightmenu.pug文件

说说

创建说说

在hexo文件夹执行下面的命令即可创建说说页

1
npx hexo new page shuoshuo

创建页面后建议修改source\shuoshuo\index.md

解析说说的代码文件在themes\liushen\layout\includes\page\shuoshuo.pug

编辑说说

说说的数据解析代码在themes\liushen\layout\includes\page\shuoshuo.pug

说说的数据存放在source_data\shuoshuo.yml

字段名 类型 说明 示例
author String 作者昵称或 ID 作者名
avatar String 作者头像的绝对网络 URL 路径 https://.../image.webp
date DateTime 发布时间,格式为 YYYY-MM-DD HH:MM:SS 2026-01-13 15:20:00
content String 动态正文,支持多行文本及 Markdown 语法 Hello World!
tags Array 字符串列表,用于对内容进行分类或标记 ["日常", "测试"]

具体格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- author: "作者名"                               # [必填] 作者昵称或名称
avatar: "https://example.com/avatar.webp" # [必填] 作者头像的完整 URL 地址
date: "2026-01-13 15:20:00" # [必填] 发布时间,格式:YYYY-MM-DD HH:MM:SS
content: "即使是微小的星光,也能照亮夜空。✨" # [必填] 正文内容,单行文本可直接书写
tags: # [可选] 标签列表,若无标签可留空或删除此项
- "日常"
- "碎碎念"

- author: "作者名"
avatar: "https://example.com/avatar.webp"
date: "2026-01-13 10:00:00"
# 使用 '>' 符号定义多行文本块,每一行前的缩进必须一致
content: >
Hello World!
这是我的第一条说说,测试一下功能是否正常。

支持 **Markdown** 语法:
1. 列表项 A
2. 列表项 B
tags:
- "测试"

主页的“说说加载中”

建议暂时把themes\liushen\layout\includes\others\memos_home.pug的第一行从if (is_home())改为if (false)来隐藏

这个说说加载中挺奇怪的,在themes/liushen/layout/includes/others/memos_home.pug中,代码定义了一个 ul.talk-list并默认显示说说加载中。。。
然而,在themes/liushen/source/js/others.js文件中,完全没有处理说说的代码。该文件包含了随机文章、导航栏隐藏、IP位置欢迎语等功能,但没有一段代码是去获取说说数据并填充到ul.talk-list中的。
并且我让AI检查是否有将数据填充进ul.talk-list的代码,结果AI没有找到任何相关代码
AI无法找到ul.talk-list相关代码

缺失的 CSS

themes\liushen\source\css\custom.styl中,定义了以下信息

1
@import '_custom/*'

经过AI分析,得出了以下信息:

  • css/_page/shuoshuo.styl:这个文件定义的是 .shuoshuo-item.shuoshuo-avatar.shuoshuo-content 等类。这些样式是给 /shuoshuo/ 这个独立页面使用的(通常是纵向排列的大卡片流)。它没有定义主页说说栏使用的 .bb_talk_swipper.talk-list#bber-talk 等类。
  • css/_page/homepage.styl:这个文件主要定义主页文章卡片(#recent-posts .recent-post-item)的布局,例如瀑布流或双栏显示。里面完全没有提到 main_top 或说说栏的相关样式。

主页说说栏的 HTML 使用了以下关键类名:

  • .bb_talk_swipper
  • .talk-list
  • .item (在 talk-list 内部)

由于在目前的 CSS 树(包括 custom.styl 导入的所有内容)中找不到这些类名的定义,浏览器只能按默认的 <ul><li> 样式显示,所以看起来就是一段没有样式的纯文字。

或许应该参考LiuShen博客的样式对其进行补全

缺失的ul.talk-list逻辑

正常来说,应该会有代码向ul.talk-list填充说说,但是并没有找到这些代码,可能需要尝试对其进行补全

友链

具体问题

貌似只有一个文件调用了flink_count.json,来自themes\liushen\layout\includes\randomlink.pug

该调用只负责了一个事情:在本地缓存失效或不存在时,从服务器获取友情链接数据以展示页脚的随机友链。

具体的代码片段如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// themes\liushen\layout\includes\randomlink.pug (片段)

50: randomLink: () => {
51: let linksData = window.liushen.loadData("links", 30);
52: if (linksData) {
// ...如果有缓存直接用...
62: } else {
63: fetch("/flink_count.json") <-- 这里发起了调用
64: .then(response => response.json())
65: .then(data => {
66: window.liushen.saveData("links", data.link_list);
67: window.liushen.randomLink();
68: });
69: }
70: }

这意味着:要让这个功能正常工作,您的站点根目录下必须能够访问到/flink_count.json

通常这需要安装插件,或者是通过某种构建脚本把 _data/links.yml转换成这个 json 文件。

如果没有生成这个文件的插件或脚本,页脚的随机友链功能就会报错(404 Not Found)。

解决方案

通过自己写一个小插件来实现自动生成flink_count.json

若需使用,将下列代码存放在themes\liushen\scripts\events\flink_generator.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
hexo.extend.generator.register('flink_count', function (locals) {
    const linksData = locals.data.links; // 读取 source/_data/links.yml
    let allLinks = [];


    if (linksData) {
        // 遍历所有分类
        linksData.forEach(item => {
            if (item.link_list) {
                // 合并该分类下的所有链接
                allLinks = allLinks.concat(item.link_list);
            }
        });
    }


    return {
        path: 'flink_count.json',
        data: JSON.stringify({
            link_list: allLinks
        })
    };
});

博客文章幻灯片

下方是预计的效果图,来自LiuShen Blog

效果图 来自LiuShen的Blog

由于开源的版本完全没有这部分的源码,打算使用网页F12拿到的html搬过来,当然,这只是设想…

字体

字体的设置在themes\liushen_config.yml,默认配置如下

1
2
3
4
5
6
7
# 全局字体设置
# 不要修改以下设置,除非你知道它们的作用
font:
global_font_size:
code_font_size:
font_family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "Microsoft JhengHei", "Microsoft YaHei", sans-serif
code_font_family:

我使用的悠哉体SourceCodeVF,并在themes\liushen\source\css\custom.styl进行引入

下面是我的custom.styl,请根据自己的配置进行更改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@import '_custom/*'

/* ==========================================================================
自定义字体配置
========================================================================== */

/* 1. 悠哉体 (Yozai) - 全局核心字体 */
@font-face
font-family: 'Yozai'
/* 悠哉体字体文件 */
src: url('/fonts/Yozai.ttf') format('truetype')
font-weight: normal
font-style: normal
font-display: swap

/* 2. Source Code Pro - 代码等宽字体 */
@font-face
font-family: 'Source Code Pro'
/* Source Code Pro 字体文件 */
src: url('/fonts/SourceCodeVF.otf') format('opentype')
font-weight: normal
font-style: normal
font-display: swap

/* APlayer 字体修正 (强制使用 Arial/Helvetica,如果某些 CSS 没有生效的话) */
.aplayer
font-family: Arial, Helvetica, sans-serif !important

右下角的菜单

菜单按钮定义存放在themes\liushen\layout\includes\rightside.pug

小猫显隐

菜单中的逻辑如下

1
2
3
4
      when 'cat'
        button#cat(onclick='toggleLive2dVisibility()', title=_p("小猫显隐"))
          i.fa-solid.fa-cat
          span.rightside-text= _p("小猫显隐")

显示/隐藏的逻辑存放在themes\liushen\source\js\others.js第150行左右

1
2
3
4
5
6
7
8
9
// 小猫的显示和隐藏
function toggleLive2dVisibility() {
    const live2dContainer = document.getElementById('live2d-widget');
    if (live2dContainer.style.display === 'block' || live2dContainer.style.display === '') {
        live2dContainer.style.display = 'none'; // 显示Live2D模型
    } else {
        live2dContainer.style.display = 'block'; // 隐藏Live2D模型
    }
}

默认是用不了的,因为没有安装Live2D,并且没有小猫的Live2D模型

音乐播放器

不知道为什么无法正常加载播放器,APlayer的教程仅供参考

在LiuShen的代码分享页找到了教程,点我前往

代码内置了对 APlayer 的支持,不过要启用这个功能,需要先去配置文件启用aplayerInject

1
2
3
4
# 注入 css 和脚本 (aplayer/meting)
aplayerInject:
  enable: true
  per_page: true

运行npm install hexo-tag-aplayer --save来安装依赖,不过安装成功后可能会出现以下提示

1
2
3
4
5
6
7
8
9
9 vulnerabilities (7 moderate, 2 high)

To address issues that do not require attention, run:
npm audit fix

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

这些提示是因为这些包中存在漏洞,不过对我们的静态网页没有任何影响

剩下的教程请参考LiuShen代码分享站

可以在文章中插入{% aplayer %}代码来播放音乐

具体的请见hexo-tag-aplayer 中文文档

分类栏

分类栏是文章上方的一个栏目,具体见图片

图片来自 LiuShen Blog

该分类栏被硬编码在themes\liushen\layout\includes\categoryBar.pug,格式如下

1
2
.category-bar-item
a(href=url_for('/链接地址/')) 显示的文字

示例:

1
2
3
4
5
6
7
8
9
10
11
12
// ...
each item in site.categories.find({ parent: { $exists: false } }).data
.category-bar-item(...)
a(href=url_for(item.path))= item.name

// --- 这里添加自定义项 ---
.category-bar-item
a(href=url_for('/photos/')) 我的相册

.category-bar-item
a(href=url_for('/archives/'))= __('文章存档')
// ...

右上角按钮

右上角的按钮被存放在themes\liushen\layout\includes\header\nav.pug,包括友链接力、随机前往一个文章等

具体格式待补充

右键菜单

菜单的显示在themes\liushen\layout\includes\rightmenu.pug

菜单的逻辑在themes\liushen\source\js\rightmenu.js(不知道为啥里面有一堆生僻字,打开巨卡)

外挂标签

因为可用的有些多,我会单独出一篇文章来介绍LiuShen主题可用的外挂标签

其他问题

右上角“随机前往一个文章点击”点击没有用

  • 确保你已安装hexo-generator-sitemap
1
npm install hexo-generator-sitemap --save
  • 确保你的文章格式为/posts/开头的,如果不是请在_config.yml中修改permalink

移除固定的蓝色背景

改好后的效果参考效果图,也就是上方半模糊的背景

截图来自 LiuShen Blog

仅需添加两行代码即可,位于themes\liushen\source\css_layout\head.styl,约18-23行

themes/liushen/source/css/_layout/head.styl CHANGED
@@ -18,4 +18,6 @@
18
  // index
19
  &.full_page
20
  height: $index_top_img_height
21
  background-attachment: fixed
 
 
 
18
  // index
19
  &.full_page
20
  height: $index_top_img_height
21
  background-attachment: fixed
22
+ background-color: transparent
23
+ background-image: none !important

目前我还在摸索这个主题怎么用,在此期间我或许会切换到其他主题。