最近觉得自己博客太单调,想加点新内容,过程稍微有点波折,故记录一下
首先是更新了markdown渲染器
原本自带的渲染器部分语法是渲染不了的,现在换成了hexo-renderer-markdown-it-plus
什么,你说为什么不是hexo-renderer-markdown-it?
由于我是在termux上写博客并推送的,其中难免遇到奇奇怪怪的问题,比如用hexo-renderer-markdown-it时,在配置文件里:
plugins:
- markdown-it-github-alerts
hexo s一下,啪!立马报错
所以采用了hexo-renderer-markdown-it-plus
骗你的,
hexo-renderer-markdown-it-plus对我现在hexo用的主题也没多好
我目前hexo用的主题是ParticleX Theme,这个主题自带语法高亮,必须禁用hexo自带的,然后我在配置文件里禁用了,依然会渲染错误代码块,根据hexo-renderer-markdown-it-plus在github上别人反馈的问题,需要手动更改库的代码更改内容如下:
// 在53-64行的开头和结尾加注释,例如这样
/*var pre_class = config['pre_class'];
if(!pre_class) pre_class = 'highlight';
checkValue(config, _res, 'highlight', function(str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return '<pre class="' + pre_class + '"><code class="' + lang + '">' + hljs.highlight(str, {language: lang, ignoreIllegals: true }).value + '</code></pre>';
} catch (__) {}
}
return '<pre class="' + pre_class + '"><code class="' + lang + '">' + utils.escapeHtml(str) + '</code></pre>';
}, function(str, lang) {
return '<pre class="' + pre_class + '"><code class="' + lang + '">' + utils.escapeHtml(str) + '</code></pre>';
});*/
这样对于我这主题就不会渲染出错了
为博客添加了live2d小人
这个倒是挺简单,运行下面命令:
npm install hexo-oh-my-live2d
也许有人要问,为什么不用
hexo-helper-live2d?
太老了,并且小人不会跟你说话,所以选择hexo-oh-my-live2d
配置文件如下,在_config.yml里:
OhMyLive2d:
enable: true
CDN: https://registry.npmmirror.com/oh-my-live2d/latest/files
# CDN: https://registry.npmmirror.com/oh-my-live2d/0.13/files/dist/index.min.js
option:
# importType: 'cubism2' # 导入类型, 默认使用全量导入: complete , 可选值: complete, cubism2, cubism5
libraryUrls: # 自定义 Cubism SDK 外部资源地址
complete: https://registry.npmmirror.com/oh-my-live2d/latest/files/lib/complete.js
cubism2: https://registry.npmmirror.com/oh-my-live2d/latest/files/lib/cubism2.js
cubism5: https://registry.npmmirror.com/oh-my-live2d/latest/files/lib/cubism5.js
# menus:
# items: |
# (defaultItems)=>{
# return [
# ...defaultItems,
# {
# id: 'github',
# icon: 'github-fill',
# title: '我的github',
# onClick: ()=>window.open('https://github.com/hacxy')
# }
# ]
# }
# items:
# - id: 'github'
# icon: 'github-fill'
# title: '我的github'
# onClick: ()=>window.open('https://github.com/k4641321')
mobileDisplay: true # 是否在移动端显示
models:
- path: /live2d_models/chino/chino.model.json
mobilePosition: [-10, 23] # 移动端时模型在舞台中的位置。 默认值: [0,0] [横坐标, 纵坐标]
mobileScale: 0.1 # 移动端时模型的缩放比例 默认值: 0.1
mobileStageStyle: # 移动端时舞台的样式
width: 180
height: 166
motionPreloadStrategy: IDLE # 动作预加载策略 默认值: IDLE 可选值: ALL | IDLE | NONE
position: [-10, 35] # 模型在舞台中的位置。 默认值: [0,0] [横坐标, 纵坐标]
scale: 0.15 # 模型的缩放比例 默认值: 0.1
# showHitAreaFrames: false # 是否显示点击区域 默认值: false
stageStyle:
width: 250
height: 250
parentElement: document.body #为组件提供一个父元素,如果未指定则默认挂载到 body 中
primaryColor: 'var(--btn-bg)' # 主题色 支持变量
sayHello: false # 是否在初始化阶段打印项目信息
tips:
style:
width: 230
height: 120
left: calc(50% - 20px)
top: -100px
mobileStyle:
width: 180
height: 80
left: calc(50% + 50px)
top: -100px
idleTips:
interval: 1000
message:
- 你好呀~
- 欢迎来到我的小站~
- 要来点咖啡吗~
- 你复制了什么内容呢?记得注明出处哦~
# 自定义提示语 需要 引入 axios 库 ,也可以使用其他方法
# message: |
# function(){
# return axios.get('https://v1.hitokoto.cn?c=i')
# .then(function (response) {
# return response.data.hitokoto ;})
# .catch(function (error) {
# console.error(error); });
# }
wordTheDay: |
function(wordTheDayData){
return `${wordTheDayData.hitokoto} by.${wordTheDayData.from}`;
}
then: |
(oml2d)=>{
setTimeout(() => {
oml2d.tipsMessage('hello world', 3000, 10);
}, 8000);
}
模型来自这里
为文章加了字数统计和阅读时间
这个也挺简单,运行下面命令:
npm install hexo-wordcount
接着在主题文件的post.ejs里的第41行后面加上:
<!-- 添加字数统计 -->
<span class="word-count">
<span class="icon">
<i class="fa-solid fa-file-word fa-fw"></i>
</span>
<%= wordcount(page.content) %> 字
</span>
<span class="reading-time">
<span class="icon">
<i class="fa-solid fa-clock fa-fw"></i>
</span>
<%= min2read(page.content) %> 分钟
</span>
为博客增加了离开和返回的标题更改与点击效果
随便网上找个模版,新建一个js文件,放在 主题文件source/js下:
var OriginTitle = document.title;
var titleTime;
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
// $('[rel="icon"]').attr('href', "/img/trhx2.png");
document.title = '别走啊,再多看看呗(*´I`*)';
clearTimeout(titleTime);
}
else {
//$('[rel="icon"]').attr('href', "/img/trhx2.png");
document.title = '欢迎回来ᴖᗜᴖ' //+ OriginTitle;
titleTime = setTimeout(function () {
document.title = OriginTitle;
}, 2000);
}
});
点击效果同理:
(function() {
var a_idx = 0;
window.onclick = function(event) {
var a = new Array(
"Perfect",
"Great",
"Good",
"Bad",
"Miss"
);
// 创建元素并防止选中
var heart = document.createElement("b");
heart.onselectstart = new Function('event.returnValue=false');
// 添加元素到页面
document.body.appendChild(heart).innerHTML = a[a_idx];
a_idx = (a_idx + 1) % a.length;
heart.style.cssText = "position: fixed; left: -100%;";
// 初始化动画参数
var f = 16, // 字体大小
x = event.clientX - f / 2, // 横坐标
y = event.clientY - f, // 纵坐标
c = randomColor(), // 随机颜色
a = 1, // 透明度
s = 1.2; // 缩放比例
// 动画定时器
var timer = setInterval(function() {
if (a <= 0) {
document.body.removeChild(heart);
clearInterval(timer);
} else {
heart.style.cssText = `
font-size: 16px;
cursor: default;
position: fixed;
color: ${c};
left: ${x}px;
top: ${y}px;
opacity: ${a};
transform: scale(${s});
`;
y--; // 垂直位移
a -= 0.016; // 透明度衰减
s += 0.002; // 持续放大
}
}, 15); // 15ms帧间隔
};
// 生成随机RGB颜色
function randomColor() {
return "rgb(" +
~~(Math.random() * 255) + "," +
~~(Math.random() * 255) + "," +
~~(Math.random() * 255) + ")";
}
})();
在layout.ejs中第87行后面加上:
<script src="<%- url_for("/js/title.js") %>"></script>
<script src="<%- url_for("/js/click.js") %>"></script>
更改了加载动画,加载文字更改成故诗
在layout.ejs中加了与更改:
<div id="loading" v-show="loading">
<div id="loading-circle">
<div id="dynamic-saying">
<span class="default-text">正在加载...</span>
</div>
<!-- <p>加载过慢请开启缓存 浏览器默认开启</p> -->
<img style="width:75%;height:75%" src="<%- url_for(theme.loading) %>" />
</div>
</div>
<script>
// 在页面加载时获取诗词并更新显示
document.addEventListener('DOMContentLoaded', function() {
const sayingElement = document.getElementById('dynamic-saying');
// 从API获取诗词
fetch('https://v1.jinrishici.com/rensheng.txt')
.then(response => response.text())
.then(data => {
if (sayingElement) {
sayingElement.innerHTML = `<span class="poem-text">${data}</span>`;
}
})
.catch(error => {
console.error('获取诗词失败:', error);
if (sayingElement) {
sayingElement.innerHTML = '<span class="poem-text">人生如逆旅,我亦是行人。</span>';
}
});
});
// 额外的CSS样式,确保诗词显示效果
const style = document.createElement('style');
style.textContent = `
.poem-text {
font-size: inherit;
font-weight: inherit;
color: inherit;
}
.default-text {
font-size: inherit;
font-weight: inherit;
color: inherit;
}
`;
document.head.appendChild(style);
</script>
评论系统恢复,使用了gitalk
这样避免免费的数据库因为没用给我收回去了
但配置好遇到了一个问题,如果lable标签超过50个字符,无法评论,网上查了使用md5编码以解决,但有人反馈还有问题
在test3文章中,测试了评论发现标签为/2025/11/20/test3/,对于我来说,只有知道文章标题就够了
我直接问deepseek
我想id只保留文章标题,不要前面路径
ai还是太好用了
deepseek给出了如下方案:
- 使用文章标题
<script>
const gitalk = new Gitalk({
clientID: "<%- theme.gitalk.clientID %>",
clientSecret: "<%- theme.gitalk.clientSecret %>",
repo: "<%- theme.gitalk.repo %>",
owner: "<%- theme.gitalk.owner %>",
admin: "<%- theme.gitalk.admin %>".split(","),
language: "<%- theme.gitalk.language %>",
id: "<%- page.title %>", // 直接使用文章标题
<% if (theme.gitalk.proxy) { %>
proxy: "<%- theme.gitalk.proxy %>",
<% } %>
})
gitalk.render("gitalk-container");
</script>
- 使用slug
我也不知道这是啥,能用就行
<script>
const gitalk = new Gitalk({
clientID: "<%- theme.gitalk.clientID %>",
clientSecret: "<%- theme.gitalk.clientSecret %>",
repo: "<%- theme.gitalk.repo %>",
owner: "<%- theme.gitalk.owner %>",
admin: "<%- theme.gitalk.admin %>".split(","),
language: "<%- theme.gitalk.language %>",
id: "<%- page.slug || page.title %>", // 优先使用slug
<% if (theme.gitalk.proxy) { %>
proxy: "<%- theme.gitalk.proxy %>",
<% } %>
})
gitalk.render("gitalk-container");
</script>
- 清理路径获取纯标题
<script>
// 从路径中提取标题
function getTitleFromPath(path) {
// 去除路径中的日期部分(如:/2024/01/01/title/)
const pathSegments = path.split('/').filter(segment => segment);
// 返回最后一个非空段,通常是标题
return pathSegments[pathSegments.length - 1] || 'default';
}
const gitalk = new Gitalk({
clientID: "<%- theme.gitalk.clientID %>",
clientSecret: "<%- theme.gitalk.clientSecret %>",
repo: "<%- theme.gitalk.repo %>",
owner: "<%- theme.gitalk.owner %>",
admin: "<%- theme.gitalk.admin %>".split(","),
language: "<%- theme.gitalk.language %>",
id: getTitleFromPath(location.pathname), // 使用处理后的标题
<% if (theme.gitalk.proxy) { %>
proxy: "<%- theme.gitalk.proxy %>",
<% } %>
})
gitalk.render("gitalk-container");
</script>
- 使用文章的唯一标识
<script>
// 使用日期+标题的组合确保唯一性
function getArticleId() {
// 如果有页面元数据,使用日期+标题
<% if (page.date && page.title) { %>
return "<%- page.date.format('YYYY-MM-DD') %>-<%- page.title %>";
<% } else { %>
return "<%- page.title %>";
<% } %>
}
const gitalk = new Gitalk({
clientID: "<%- theme.gitalk.clientID %>",
clientSecret: "<%- theme.gitalk.clientSecret %>",
repo: "<%- theme.gitalk.repo %>",
owner: "<%- theme.gitalk.owner %>",
admin: "<%- theme.gitalk.admin %>".split(","),
language: "<%- theme.gitalk.language %>",
id: getArticleId(), // 生成唯一的id
<% if (theme.gitalk.proxy) { %>
proxy: "<%- theme.gitalk.proxy %>",
<% } %>
})
gitalk.render("gitalk-container");
</script>
我选择了slug的方案,最后评论的标签像这样:
APlayer配置留存
能用👍🏻