一个用于哔哩哔哩硬核会员搜题的 Tampermonkey 脚本。
F12
), 将浏览器切换为移动设备(Ctrl+Shift+M
);https://www.bilibili.com/h5/senior-newbie/qa
并回车,等待网页加载完成;Alt+N
);txt
,doc
,docx
,xls
,xlsx
格式),题库中搜索不到则使用搜索引擎搜索百度
,搜狗
,必应
,谷歌
)文史
,知识
,音乐
等答案比较好搜索判断的类型。在静态网站上实现浏览记录功能,浏览记录保存在用户本地。
下载visit-history.min.js文件;
在你的网页中插入
<script src="path/to/visit-history.min.js"></script>
或直接使用CND
<script src="https://cdn.jsdelivr.net/gh/HCLonely/visit-history@1visit-history.min.js"></script>
const { visitHistory } = require('visit-history');visitHistory.set({ data: { }, // [必需]保存的数据 identifier: () => window.location.pathname, // [可选]网页的位移标识符, 默认为 () => window.location.pathname limit: 20 // [可选]最大保存的浏览历史数量,默认为 20});
Example:
const { visitHistory } = require('visit-history');visitHistory.set({ data: { title: document.querySelector('title').innerText.trim(), link: window.location.href }, identifier: () => window.location.href, limit: 30});
const { visitHistory } = require('visit-history');visitHistory.get({ htmlTemplate: '', // [可选]Html模板, 使用'{{key}}'替换data中的变量. 留空则返回保存的data数据, 默认为空 limit: 10 // [可选]读取的浏览记录数量, 留空则返回所有数据, 默认为空});
Example:
const { visitHistory } = require('visit-history');const history = visitHistory.get({ htmlTemplate: '<div class="title><a href="{{link}}">{{title}}</a></div>', limit: 10});document.querySelector('.history').innerHTML = history.join('');
注意:此模块仅作推送使用,不可交互 !!!
统一化推送服务Nodejs API. 已支持钉钉, Discord, 邮件, 飞书, PushDeer, PushPlus, QQ, QQ 频道机器人, Server 酱, Showdoc Push, Telegram Bot, 企业微信群机器人, 息知, WxPusher, NowPush, iGot, Chanify, Bark, Push, Slack, Pushback, Zulip, RocketChat, Gitter等平台.
npm install all-pusher-api -S
const { PushApi } = require('all-pusher-api'); // 多平台同时推送(async () => { console.log((await new PushApi([ { name: 'ServerChanTurbo', config: { key: { token: '******' } } }, { name: 'PushDeer', config: { key: { token: '******' } } }, { name: 'WxPusher', config: { key: { token: '******', uids: ['******'] } } } ]) .send({ message: '测试文本' })).map((e) => (e.result.status >= 200 && e.result.status < 300) ? `${e.name} 测试成功` : e));})();
(async () => { // Example 1 const { PushApi } = require('all-pusher-api'); // 多平台同时推送 const result = await new PushApi([ { name: 'ServerChanTurbo', config: { key: { token: '******' } } } ]) .send({ message: '测试文本' }); console.log(result.map((e) => (e.result.status >= 200 && e.result.status < 300) ? `${e.name} 测试成功` : e)); // Example 2 const { WxPusher } = require('all-pusher-api/dist/WxPusher'); // 单平台推送可选 const wxPusherResult = await new WxPusher({ token: '******', uids: ['******'] }) .send({ message: '测试文本' }); console.log(wxPusherResult);})();
(async () => { const { DingTalk } = require('all-pusher-api/dist/DingTalk'); const result = await new DingTalk({ key: { token: '******', secret: '******' } }) .send({ message: '这条消息@了所有人', extraOptions: { isAtAll: true } }); console.log(result);})();
这里以钉钉为例
(async () => { const { DingTalk } = require('all-pusher-api/dist/DingTalk'); const result = await new DingTalk({ key: { token: '******', secret: '******' } }) .send({ customOptions: { "msgtype": "actionCard", "actionCard": { "title": "我 20 年前想打造一间苹果咖啡厅, 而它正是 Apple Store 的前身", "text": "![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png) \n\n #### 乔布斯 20 年前想打造的苹果咖啡厅 \n\n Apple Store 的设计正从原来满满的科技感走向生活化, 而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划", "btnOrientation": "0", "btns": [ { "title": "内容不错", "actionURL": "https://www.dingtalk.com/" }, { "title": "不感兴趣", "actionURL": "https://www.dingtalk.com/" } ] } } }); console.log(result);})();
(async () => { const { Custom } = require('all-pusher-api/dist/Custom'); // 自定义接口只能通过此方法引入 const { createHmac } = require('crypto'); const sign = () => { const timestamp = new Date().getTime(); const secret = '******'; const stringToSign = `${timestamp}\n${secret}`; const hash = createHmac('sha256', secret) .update(stringToSign, 'utf8') .digest(); return `timestamp=${timestamp}&sign=${encodeURIComponent(hash.toString('base64'))}`; }; console.log(await new Custom({ url: `https://oapi.dingtalk.com/robot/send?access_token=******&${sign()}`, success: { key: 'responseData.errcode', value: 0 } }).send({ msgtype: 'text', text: { content: '测试文本' } })); /* 返回值 { status: 200, statusText: 'Success', extraMessage: <AxiosResponse> } */});
这部分写的比较乱,建议配合参数生成器使用!
const pusher = new WxPusher(pusherConfig);
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
token | string | null | 大部分平台的授权token, 如果有授权信息有多个, 请使用key |
baseUrl | string | null | 对于部分支持搭建服务端的平台, 如果使用自建服务端, 需配置此选项 |
webhook | string | null | Discord , 企业微信机器人 , RocketChat 和GoogleChat 的 webhook 地址, 该平台请使用webhook 而不是token |
userId | string | null | Pushback 平台的 User_id |
chat_id | string | null | Telegram 平台的 chat_id |
email | string | null | Zulip 平台的 bot email |
domain | string | null | Zulip 平台的 domain |
to | Array<number\|string> | null | Zulip 平台的发送对象 |
roomId | string | null | Gitter 平台发送对象的 roomid |
baseUrl | string | null | go-cqhttp 的http通信地址, 以http:// 或https:// 开头 |
user_id | number | null | 使用 go-cqhttp 推送时的目标 QQ 号, 此参数与group_id , channel_id 二选一 |
group_id | number | null | 使用 go-cqhttp 推送时的目标群号, 此参数与user_id , channel_id 二选一 |
channel_id | string | null | 使用 go-cqhttp 推送时的目标频道ID, 此参数与user_id , group_id 二选一, 且必须与guild_id 同时存在 |
guild_id | string | null | 使用 go-cqhttp 推送时的目标子频道ID, 此参数必须与channel_id 同时存在 |
corpid | string | null | 企业微信群机器人的corpid |
agentid | string | null | 企业微信群机器人的agentid |
secret | string | null | 钉钉、飞书加签的密钥[可选]/企业微信群机器人的secret |
touser | string | null | 企业微信群机器人指定接收消息的成员, 也可在sendOptions中配置 |
uids | Array<string> | null | WxPusher 发送目标的 UID, 也可在sendOptions中配置 |
topicIds | Array<number> | null | WxPusher 发送目标的 topicId, 也可在sendOptions中配置 |
appID | string | null | QQ频道机器人的 ID, 使用QQ频道推送时此选项为必选 |
token | string | null | QQ频道机器人的 token, 使用QQ频道推送时此选项为必选 |
sandbox | boolean | false | 使用QQ频道推送时是否启用沙箱, 可选 |
channelID | string | null | QQ频道的子频道 ID, 使用QQ频道推送时此选项为必选 |
user | string | null | Pushover 的 user key, 使用 Pushover 推送时此选项为必选 |
key | object | null | 以上参数都可以放到key 中, 示例 |
- key.host | string | null | 邮件发送服务器地址, 使用邮件推送时此选项为必选 |
- key.port | number | null | 邮件发送服务器端口, 使用邮件推送时此选项为必选 |
- key.secure | boolean | false | 邮件发送服务器是否启用TLS/SSL, 可选 |
- key.auth | object | null | 邮件发送服务器的验证信息, 使用邮件推送时此选项为必选 |
- key.auth.user | string | null | 邮件发送服务器的用户名, 使用邮件推送时此选项为必选 |
- key.auth.pass | string | null | 邮件发送服务器的密码, 使用邮件推送时此选项为必选 |
proxy | object | null | 代理配置, 可选, 部分支持 |
- proxy.enable | boolean | false | 是否启用代理 |
- proxy.protocol | string | 'http' | 代理协议 |
- proxy.host | string | null | 代理主机地址 |
- proxy.port | number | null | 代理端口 |
- proxy.username | string | null | 代理用户名 |
- proxy.password | string | null | 代理密码 |
自定义接口
const customPusher = new Custom(CustomConfig);
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
url | string | null | 请求链接, 必需 |
method | string | 'POST' | 请求方式, 可选 |
contentType | string | 'application/json' | 发送的数据类型, 等同于hreders['Content-type'] |
headers | AxiosRequestHeaders | null | 请求头, 可选 |
success | object | null | 推送成功的判断方式, 必需 |
- success.key | string | null | 请看示例 |
- success.value | any | null | 请看示例 |
key | object | null | 以上参数都可以放到key中 |
proxy | object | null | 代理配置, 同上 |
const pushers = new PushApi(pushersConfig);
const pushersConfig: Array<{ name: string, config: pusherConfig}>
const result = await pusher.send(sendOptions);
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
message | string | null | 推送的消息内容, message 与customOptions 至少要有一个 |
title | string | null | 部分平台支持消息标题, 不填则自动提取message 第一行的前10个字符 |
type | string | 'text' | 仅支持text , markdown , html . 具体平台支持情况请查看支持的消息类型 |
extraOptions | object | null | 附加内容, 此对象中的内容会附加到请求体中, 示例 |
customOptions | object | null | 自定义请求内容, 推送时会POSTcustomOptions , 示例 |
const result = await customPusher.send(customSendOptions);
customSendOptions
会直接作为请求体发送, 具体请查看示例.
const results = await pushers.send(pushersSendConfig);
const pushersSendConfig: Array<{ name: string config: pushersSendConfig}>
const result = await pusher.send(sendOptions);
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
status | number | null | 状态码 |
statusText | string | null | 状态说明文本 |
extraMessage | AxiosResponse | Error | null |
const results = await pushers.send(pushersSendConfig);
const results: Array<{ name: string result: result}>
所有平台支持均纯文本(
text
)格式消息, 大部分支持markdown
格式消息, 部分支持html
格式消息
markdown*
为支持html
格式不支持markdown
格式消息时自动将markdown
转换为html
格式
other
为部分平台支持特殊格式的消息, 可通过customOptions
传入参数, 具体参数请查看相应平台的文档
text
text
text
, other
text
, other
text
, other
text
, other
text
, other
text
, other
text
, other
text
, markdown
text
, markdown
text
, markdown
, other
text
, markdown
, other
text
, markdown
, other
text
, markdown
, other
text
, markdown
, other
text
, markdown
, html
text
, markdown*
, html
text
, markdown*
, html
text
, markdown*
, html
0
-Missing Parameter: ***
: 缺少必要参数10
-Missing Options
: 缺少发送消息配置11
-Unknown Error
: 未知错误200
-Success
: 推送成功201
-Waiting
: 待审核100
-Error
: 请求发送成功, 服务器返回错误信息101
-No Response Data
: 请求发送成功, 但没有接收到服务器返回的数据102
-Request Error
: 请求发送失败, 一般是网络问题103
-Options Format Error
: 参数格式错误104
-Get "***" Failed
: 获取参数失败140
-Check Sign Failed
: 签名校检失败安装Tampermonkey或类似浏览器扩展(脚本基于此扩展使用)
安装此脚本
使用前先在Tampermonkey
中启用此脚本;
点击浏览器的Tampermonkey
扩展图标,找到此脚本下面的启动启动选项并点击;
按要求选择模式
选择题目后会弹出搜
按钮,点击此按钮即可搜索;
用完记得关闭此脚本,否则可能会造成访问其他网页出现BUG;
开启 X5 内核: debugmm.qq.com/?forcex5=true
复制这个在微信团队后点开或用微信扫描二维码
出现下图说明开启成功
安装 X5 内核(以下线上与本地内核二选一)
http://debugtbs.qq.com
复制这个在微信发送出去后打开下载线上内核,重启即可;/sdcard/Android/data/com.tencent.mm/files/tbs
目录(没有这个目录的话新建一个),然后回到 http://debugtbs.qq.com
点击安装本地内核,安装完成后重启微信;打开vConsole调试功能:http://debugx5.qq.com
复制这个在微信发送出去后打开,选择顶部信息
,下面勾选打开vConsole调试功能
在大学习界面点击右下角的绿色按钮,在弹出的控制台输入下面的代码(最好等视频加载完开始播放后在执行,太快了可能没反应,没反应的话再输一遍就好了)
var videoEle = document.getElementsByTagName('video')[0]; // 获取播放器元素videoEle.controls = true; // 显示进度条videoEle.currentTime = videoEle.duration; // 时间拉到最后videoEle.ended = true; // 视频播放结束score = 100; // 成绩__vconsole.style.display = 'none'; // 隐藏右下角绿色按钮
启用Inspector调试功能:
打开TBS内核Inspector调试功能
;debugmm.qq.com/?forcex5=false
复制这个在微信团队后点开或用微信扫描二维码http://debugxweb.qq.com/?inspector=true
,等加载完关闭就行手机通过数据线连接电脑并启用 USB 调试功能(如何打开?)
点击ADB扩展图标,点击View Inspaction Targets
(如果手机上弹出是否允许调试,点击允许)
在弹出的页面上勾选Discover USB devices
和Discover network targets
打开大学习页面,等待加载设备,出现如下图所示
手机上开始播放视频,电脑上点击inspect
,在弹出的窗口右侧一栏点击控制台
或Console
在控制台输入以下代码:
var videoEle = document.getElementsByTagName('video')[0]; // 获取播放器元素videoEle.controls = true; // 显示进度条
手机上拖动进度条跳过
此方法需要手机 root, 并安装XPosed框架,这里建议安装LSPosed框架!
具体支持情况点此查看
如果你不了解 Root, XPosed, Lsposed, 刷机等内容,请不要使用此方法!
此方法默认你已安装 XPosed 框架并可用!
公主连结Re:Dive
的词库pcr-dict。pcr-dict.zip
文件,解压后导入即可。git clone https://github.com/HCLonely/live2dNodeApi.git
cd live2dNodeApi
npm i -S
或cnpm i -S
npm start
命令 | 功能 | 额外说明 |
---|---|---|
npm start | 启动 api 服务器 | |
npm run update | 重新生成modelList.json 文件 | 用于增加或删除模型后更新模型列表 |
npm run check | 检测模型的主配置文件格式及模型文件的完整性 | |
npm run screenshot | 生成模型的预览图,放在preview 文件夹 | |
npm run pre | 在网页上查看模型的预览图,需要先生成 |
修改config.json
文件进行配置:
{ "port": 2333, // 监听端口,默认2333 "ssl":{ "enable":false, // 是否启用ssl "privateCrt":"", // ssl证书文件路径 "privateKey":"" // ssl私钥文件路径 }}
models├─模型文件夹 # 同一角色不同皮肤,不同皮肤共用一个index.json文件│ ├─index.json # 必须,或model.json│ └─...├─模型文件夹 # 同一角色不同皮肤,每个皮肤都有各自的index.json文件│ ├─模型文件夹 # 单个模型│ │ ├─index.json # 必须,或model.json│ │ └─...│ └─模型文件夹 # 单个模型│ ├─index.json # 必须,或model.json│ └─...└─模型文件夹 # 单个模型 ├─index.json # 必须,或model.json └─...
详情请参考models目录
请重命名模型文件夹进行排序,参考models目录。
]]>在pjax:complete
添加以下回调:
if(typeof _hmt !== "undefined" && typeof _hmt.push === "function") _hmt.push(['_trackPageview',window.location.pathname]);
谷歌分析似乎有两种,请根据你引用的 js 库修改:
https://www.google-analytics.com/analytics.js
https://www.googletagmanager.com/gtag/js?id=UA-*******
在pjax:complete
添加以下回调:
if(typeof ga === "function") ga('send', 'pageview', window.location.href);
在pjax:complete
添加以下回调(感谢@FGHRSH):
if(typeof gtag === "function") gtag('event', 'pageview', {page_location: window.location.href});
]]>注意:此插件会和hexo g
命令冲突,请使用hexo ge
或hexo generate
替代hexo g
命令!
注意:不满足前提条件的无法使用此插件,在不满足前提条件的情况下安装此插件出现的问题不予以处理,如何实现以下前提条件的问题不予以处理!
git log -1 --date=iso --pretty=format:"%ad"
命令能够输出一个日期;.git
文件夹,这是一个隐藏文件夹;npm i hexo-calendar -S
or
cnpm i hexo-calendar -S
<%- calendar({monthLang: 'cn', dayLang: 'cn', title: '活动日历'}) %>
注意:这种方法请使用严格的 JSON 格式!
{% calendar %}{"monthLang": "cn", "dayLang": "cn", "title": "活动日历"}{% endcalendar %}
如果你使用了Travis CI
, Github Action
之类的自动部署,那么你需要在推送源码之前使用hexo gc -w=40
命令生成一个calendar.json
文件。-w=40
代表显示 40 周之前至今的活动记录。
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
width | String | "600" | 日历宽度,单位:px |
height | String | "165" | 日历高度,单位:px |
id | String | "calendar" | 日历元素 id |
monthLang | String or Array | "en" | 月份语言,可选:en , cn 或自定义 |
dayLang | String or Array | "en" | 一周中每一天的语言,可选:en , cn 或自定义 |
weeks | Number | 40 | 显示多少周之前至今的活动记录 |
title | String | "calendar" | 日历标题 |
insertScript | Boolean | true | 是否自动插入echarts 库。如果你已全局引入echarts 库,请将此项设为false ;如果你的站点启用了pjax ,请将此项设为false ,并全局引用echarts 库。 |
Settings
Developer settings
Personal access tokens
Generate new token
创建一个token
Note
随便填就行,Select scopes
勾选repo
给与 repo 操作权限,然后拉到最下面点击Generate token
即可以https://github.com/user/repo.git
仓库为例,只需要在仓库前面添加x-access-token:**************@
即可,************
替换成上一步的 token
https://x-access-token:**************@github.com/user/repo.git
个人设置
访问令牌
新建令牌
创建一个令牌
令牌描述
随便填就行,选择权限
勾选project:depot
给与仓库操作权限,然后拉到最下面点击创建令牌
即可以https://e.coding.net/user/project/repo.git
仓库为例,只需要在仓库前面添加用户名:令牌@
即可,用户名
和令牌
替换成上一步的用户名和令牌
https://*****:***********@e.coding.net/user/project/repo.git
设置
私人令牌
生成新令牌
创建一个令牌
私人令牌描述
随便填就行,请选择将要生成的私人令牌所拥有的权限
勾选projects
给与仓库操作权限,如果弄需要Pull Requests
那就把下面的pull_requests
也勾选上,然后拉到最下面点击提交
即可以https://gitee.com/user/repo.git
仓库为例,只需要在仓库前面添加oauth2:**********
即可,**********
替换成上一步的令牌
https://oauth2:**********@gitee.com/user/repo.git
安全起见,如果你使用公共电脑进行仓库的 push&pull 操作,请在离开时删除你的代码仓库,如果你之后还要用不想删除代码仓库,请使用git remote rm
命令把仓库链接删掉!
一款基于WebStackPage的 Hexo 主题。Demo
git clone https://github.com/HCLonely/hexo-theme-webstack themes/webstack
网站图标
示例:
favicon: /favicon.ico
[可选]分享网站到 twitter 和 facebook 时的图片。
示例:
banner: /images/webstack_banner_cn.png
网站 logo
expanded
: 侧边栏展开时左上角的 logocollapsed
: 侧边栏收起时左上角的 logodark
: 顶栏为暗色时左上角的 logo, 仅 about
页面生效示例:
logo: expanded: /images/logo@2x.png collapsed: /images/logo-collapsed@2x.png dark: /images/logo_dark@2x.png
语言标识,多语言请配合子页面使用
flag-cn
和flag-us
, 其他图标自行寻找存放于主题目录/source/images/flags/
示例:
flag: - name: Chinese default: true icon: flag-cn index: /index.html
是否显示搜索框
示例:
search: true
自定义搜索引擎
url(图片链接)
url(图片链接)
示例:
userDefinedSearchData: custom: true thisSearch: https://www.baidu.com/s?wd= thisSearchIcon: url(https://www.baidu.com/favicon.ico) hotStatus: true data: - name: 百度 img: url(https://www.baidu.com/favicon.ico) url: https://www.baidu.com/s?wd= - name: 谷歌 img: url(https://www.google.com/favicon.ico) url: https://www.google.com/search?q=
右上角的 github corner
示例:
githubCorner: '<a href="https://github.com/HCLonely/hexo-theme-webstack" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>'
建站年份,显示在页面底部
示例:
since: 2020
[主要]侧边栏菜单设置
config
, 此选项内容包含name
, icon
, config
选项示例:
menu: - name: 常用工具 icon: far fa-star config: hotTools - name: 其他工具 icon: fas fa-tools submenu: - name: 开发工具 icon: fas fa-tools config: devTools - name: 我的博客 icon: fas fa-blog config: myBlog
是否将侧边栏全部展开
示例:
expandAll: true
侧边栏的关于本站
示例:
about: url: /about/ icon: far fa-heart name: 关于本站
关于页面设置
hexo new page about
source/about/index.md
, 添加type: 'about'
---title: aboutdate: 2020-06-04 18:11:54type: 'about'---
aboutPage
html
语法html
语法示例:
aboutPage: website: head: 关于本站 html: '<blockquote><p>本站是hexo主题<a href="https://github.com/HCLonely/hexo-theme-webstack">hexo-theme-webstack</a>的demo站。</p></blockquote>' webmaster: head: 关于站长 name: HCLonely url: https://blog.hclonely.com/ img: /images/logos/myblog.png description: 懒人一个 html: '<br /><blockquote><p>本站是<a href="https://github.com/HCLonely">HCLonely</a>基于<a href="https://github.com/WebStackPage/WebStackPage.github.io">WebStackPage</a>项目做的一款<a href="https://hexo.io/">Hexo</a>主题。</p></blockquote>'
不蒜子统计
footer
显示在页脚, sidebar
显示在侧边栏$pv
会被替换为访问量$uv
会被替换为访客数示例:
busuanzi: enable: true position: sidebar pv: 本站总访问量$pv uv: 本站总访客数$uv
自定义
html
内容
<head></head>
标签内的内容</body>
标签之前的内容示例:
custom: head: |- # 以下内容插入到<head></head>标签内,可设置多行,注意每行开头至少四个空格 <link rel="stylesheet" type="text/css" href="custom.css"> <script src="custom.js"></script> body: |- # 以下内容插入到</body>标签之前,可设置多行,注意每行开头至少四个空格 <div>custom text</div> <script src="custom.js"></script>
[主要]网站内容设置
示例:
- name: HCLonely Blog url: https://blog.hclonely.com/ img: /images/logos/myBlog.png description: 一个懒人的博客。
在menu
和submenu
中设置的config
的内容为此选项的名称。
例menu
:
menu: - name: 常用工具 icon: far fa-star config: hotTools
则常用工具
分组里的网站有以下两种添加方式:
_config.yml
里添加:hotTools: - name: HCLonely Blog url: https://blog.hclonely.com/ img: /images/logos/myBlog.png description: 一个懒人的博客。 - name: Github url: https://github.com/ img: /images/logos/github.png description: 面向开源及私有软件项目的托管平台。
站点根目录/source/_data/
(没有自行创建)内新建hotTools.yml
文件,文件内容如下:- name: HCLonely Blog url: https://blog.hclonely.com/ img: /images/logos/myBlog.png description: 一个懒人的博客。- name: Github url: https://github.com/ img: /images/logos/github.png description: 面向开源及私有软件项目的托管平台。
以上两种方式任选一种即可,建议使用第二种。
使用hexo new page xxx
创建子页面,这里包括下面的说明都以hexo new page child
为例。
使用上面的命令生成子页面后,打开根目录/source/child/index.md
文件(子页面配置文件),在两个---
之间添加一行type: 'child'
使此配置文件生效,子页面默认使用主页的配置,子页面优先使用子页面配置文件两个---
之间的配置,各配置项和主页的配置功能相同。
示例请看https://github.com/HCLonely/hexo-theme-webstack/tree/gh-pages/source/child/index.md
]]>由于子页面在很久之前就基本做完了,后来比较忙就鸽了,可能有些配置或 bug 给忘了,有问题请及时反馈!
所以这里介绍一个使用第三方计划任务网站进行定时唤醒 Valine-admin 的方法。
注册地址:https://cron-job.org/en/signup/
注册时的时区请选择Asia/Shanghai
登陆之后依次点击Members
,cronjobs
,Create cronjob
Title, Address
Title
可以随便填一个Address
填写你的云引擎环境变量的ADMIN_URL
,也就是 Leancloud 的Web 主机域名
。如果你用的我Valine 添加博主标签及评论微信、QQ 通知文章里的最新版的仓库,还需要在后面加上/start
,当然也可以不加,加上会有唤醒日志。Schedule
User-defined
进行自定义设置Days of month
: 全选Days of week
: 全选Months
: 全选Hours
: 你需要在哪个时间段唤醒就选择什么Minutes
: 选择0
,20
,40
Notifications
Common
Save responses
, 保存唤醒日志点击Create cronjob
本教程介绍了如何给 Valine 评论系统添加博主
、小伙伴
、 访客
标签,添加浏览器
及操作系统图标
,以及评论微信
及QQ
通知。
建议有一定 JS 基础的用户根据本教程进行自定义修改,至少能够自己找到为什么会报错,否则不建议修改!
基于https://github.com/xCss/Valine修改。
由于 1.4.0 以后 Valine 作者不再发布源码,所以这里不说如何修改了,只放出我修改好的 js 链接及使用方法。
参数如何添加请查看 Demo 站源码的butterfly.yml 文件和valine.pug 文件
https://cdn.jsdelivr.net/gh/HCLonely/Valine@latest/dist/Valine.min.js
博主
,小伙伴
,访客
标签浏览器
和操作系统
图标,需fontawesomeV5
支持meta placeholder
可自定义本版比原版多了以下参数:
参数 | 类型 | 说明 | 默认 | 示例 |
---|---|---|---|---|
tagMeta | Array | 标签要显示的文字 | [“博主”,“小伙伴”,“访客”] | [“博主”,“小伙伴”,“访客”] |
master | Array/String | md5 加密后的博主邮箱 | [] | [“fe01ce2a7fbac8fafaed7c982a04e229”] |
friends | Array | md5 加密后的小伙伴邮箱 | [] | [“fe01ce2a7fbac8fafaed7c982a04e229”] |
metaPlaceholder | Object | meta placeholder 内容 | {} | {“nick”:“昵称/QQ 号”,“mail”:“邮箱(必填)”} |
基于https://github.com/DesertsP/Valine-Admin修改。
修改方法不在多说,直接使用我的源码即可,如果你有一定的 NodeJS 知识,可以参考我的源码自行修改。
注意!由于 leancloud 的原因,自动唤醒任务可能会失败!
https://github.com/HCLonely/Valine-Admin.git
基本方法同原版相同,请先查看原版使用文档并配置好。
本版比原版多了以下参数:
变量 | 示例 | 说明 |
---|---|---|
SERVER_KEY | SCUxxxxxxxx | [可选]Server酱 SCKEY 用于微信通知 |
SERVER_TURBO_KEY | SCTxxxxxxxx | [可选]Server酱·Turbo版 SendKey 用于微信通知 |
SERVER_TURBO_MD | true | [可选]使用Server酱·Turbo版通知时是否使用 MD 模板,默认为false |
QMSG_KEY | xxxxxxxx | [可选]Qmsg key 用于 QQ 通知 |
QQ_SHAKE(已失效) | true | [可选]QQ 通知时发送戳一戳 |
DISABLE_EMAIL | true | [可选]禁止邮件通知博主,@仍然会提醒 |
TEMPLATE_NAME | rainbow | [可选]rainbow 或default 邮件通知模板 |
邮件通知模板在云引擎环境变量中设定,可自定义通知邮件标题及内容模板。
环境变量 | 示例 | 说明 |
---|---|---|
MAIL_SUBJECT | ${PARENT_NICK},您在${SITE_NAME}上的评论收到了回复 | [可选]@通知邮件主题(标题)模板 |
MAIL_TEMPLATE | 见下文 | [可选]@通知邮件内容模板 |
MAIL_SUBJECT_ADMIN | ${SITE_NAME}上有新评论了 | [可选]博主邮件通知主题模板 |
MAIL_TEMPLATE_ADMIN | 见下文 | [可选]博主邮件通知内容模板 |
邮件通知包含两种,分别是被@通知和博主通知,这两种模板都可以完全自定义。默认使用经典的蓝色风格模板(样式来源未知)。
默认被@通知邮件内容模板如下:
<html> <head></head> <body> <table style="width: 99.8%;height:99.8% "> <tbody> <tr> <td> <div style="border-radius: 10px 10px 10px 10px;font-size:13px; color: #555555;width: 666px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"> <div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"> <p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您在<a style="text-decoration:none;color: #ffffff;" href="<%=siteUrl%>"> <%=siteName%> </a>上的留言有新回复啦! </p> </div> <div style="margin:40px auto;width:90%"> <p><%=pname%> 同学,您曾在文章上发表评论:</p> <div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;"><%-ptext%></div> <p><%=name%> 给您的回复如下:</p> <div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;"><%-text%></div> <p>您可以点击 <a style="text-decoration:none; color:#12addb" href="<%=url%>">查看回复的完整內容 </a>,欢迎再次光临 <a style="text-decoration:none; color:#12addb" href="<%=siteUrl%>"> <%=siteName%> </a>。</p> <style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style> </div> </div> </td> </tr> </tbody> </table> </body> </html>
@通知模板中的可用变量如下(注,这是邮件模板变量,请勿与云引擎环境变量混淆):
模板变量 | 说明 |
---|---|
<%=siteName%> | 博客名称 |
<%=siteUrl%> | 博客首页地址 |
<%=url%> | 文章地址(完整路径) |
<%=pname%> | 收件人昵称(被@者,父级评论人) |
<%-ptext%> | 父级评论内容 |
<%=name%> | 新评论者昵称 |
<%-text%> | 新评论内容 |
默认博主通知邮件内容模板如下:
<html> <head> <style> .wrap span { display: inline-block; } .w260{ width: 260px;} .w20{ width: 20px;} .wauto{ width: auto;} </style> </head> <body> <table style="width: 99.8%;height:99.8% "> <tbody> <tr> <td> <div style="border-radius: 10px 10px 10px 10px;font-size:13px; color: #555555;width: 666px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"> <div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"> <p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您的<a style="text-decoration:none;color: #ffffff;" href="<%=siteUrl%>"> <%=siteName%> </a>上有新的评论啦! </p> </div> <div style="margin:40px auto;width:90%"> <p><%=name%> 发表评论:</p> <div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;"><%-text%></div> <p><a style="text-decoration:none; color:#12addb" href="<%=url%>" target="_blank">[查看评论]</a></p> <style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style> </div> </div> </td> </tr> </tbody> </table> </body> </html>
博主通知邮件模板中的可用变量与@通知中的基本一致,<%=pname%>
和 <%-ptext%>
变量不再可用。
前往Coding注册一个帐号
登录后点击右上角的Cloud Studio
点击设置,将 ssh 公钥添加到Coding
或Github
或者其他的 Git 仓库的个人公钥列表
点击工作空间,新建工作空间
工作空间名称
能自己看懂就行,运行环境
选择预置环境
、Node.js
,代码来源
选空
,然后创建
点击刚刚创建的工作空间
按下键盘Ctrl+~打开终端
按照官方教程依次输入以下命令就可以了
npm install hexo-cli -ghexo init blogcd blognpm install
到这里一个博客就基本搭建完成了,其他的去看Hexo 官方文档就可以了
工作空间名称
能自己看懂就行,运行环境
选择预置环境
、Node.js
,代码来源
选仓库
,并在下面输入你源码仓库的SSH
地址,然后创建
点击刚刚创建的工作空间,它会自动克隆你的源码,你只需要运行npm install
命令安装所需依赖就可以了
我们在本地只需运行hexo server
就可以在http://localhost:4000
预览了,不过用Cloud Studio
的话运行hexo server
命令后,需要Ctrl+Shift+P打开命令面板,输入preview
,选择Preview: Open Preview Tab
输入端口号(默认 4000)回车就可以了
如果你用过 Vscode, 下面可以不用看了,安装你喜欢的插件就可以了
点击左边的Extensions
可以安装扩展,这里推荐几个适用于编辑 Hexo 的插件
在欢迎使用
页面点击安装对JavaScript
的支持,右下角会有弹窗,确定即可
Markdown 预览插件
]]>之前搞网页 Live2d 模型的时候在网上找了很多文章,但大部分都只支持
moc
格式的模型,不支持moc3
格式的模型。
如果你的模型是
moc
格式,请参考给网页添加一个 Live2D 看板娘(前端)
最近在Github上看到这个项目AzurLaneL2DViewer, 根据这个项目做成了 JS 库。
使用前请查看live2dcubismcore
的许可协议
在<body>
标签内添加如下内容:
<!-- 用于存放Live2d的元素,可自定义 --><div class="Canvas" style="position: fixed; right: 10px; bottom: 10px;z-index: 99999999" id="L2dCanvas"></div>
在</body>
之前添加以下内容:
<!------ 位置可自定义 ------><div class="Canvas" style="position: fixed; right: 10px; bottom: 10px;z-index: 99999999" id="L2dCanvas"></div><!------ 依赖 JS ------><!---- 可选 ----><!-- 兼容低版本浏览器 --><script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"> </script><!-- 音频播放兼容 --><script src="https://cdn.jsdelivr.net/npm/howler@2.1.3/dist/howler.min.js"></script><!---- 必需 ----><script src="https://cubism.live2d.com/sdk-web/cubismcore/live2dcubismcore.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pixi.js@4.6.1/dist/pixi.min.js"></script><!-- live2dv3.js --><script src="https://cdn.jsdelivr.net/npm/live2dv3@1.2.2/live2dv3.min.js"></script><!------ 加载Live2d模型 ------><script>window.onload = () => { new l2dViewer({ el: document.getElementById('L2dCanvas'), // 要添加Live2d的元素, 支持dom选择器和jq选择器 basePath: 'https://cdn.jsdelivr.net/gh/HCLonely/Live2dV3/assets', // 模型根目录 modelName: 'biaoqiang_3', // 模型名称 sounds: [ // 触摸播放声音 'sounds/demo.mp3', // 相对路径是相对于模型文件夹 'https://cdn.jsdelivr.net/npm/live2dv3@latest/assets/biaoqiang_3/sounds/demo.mp3' // 也可以是网址 ] })}</script>
参数 | 类型 | 描述 | 默认 |
---|---|---|---|
el | [必需] DOM 对象或 jQuery 对象 | 要挂载 Live2d 模型的元素, 支持 DOM 选择器和 jQuery 选择器,例:document.getElementById('L2dCanvas') 或document.querySelector('#L2dCanvas') 或$('#L2dCanvas') | null |
basePath | [必需] String | 模型根目录 | null |
modelName | [必需] String | 模型目录 | null |
width | [可选] Number | Canvas 宽度,单位: px | 500 |
height | [可选] Number | Canvas 高度,单位: px | 300 |
sizeLimit | [可选] Boolean | 当窗口大小小于设置的宽或高时不加载模型 | false |
mobileLimit | [可选] Boolean | 移动端不加载模型 | false |
sounds | [可选] Array | 触摸播放声音, 留空则不播放 | null |
modelName
?)重新加载/更换模型
用于在 Hexo 博客中嵌入 steam 游戏。
npm install hexo-tag-steamgame --save
{% steamgame appid description %}```* 批量嵌入游戏```Nunjucks{% steamgames %}appidappidappidappidappidappid{% endsteamgames %}
appid: Steam 游戏 id.description(可选): 用于替换默认游戏简介。
{% steamgame 1057090 %}```{% steamgame 1057090 %}```Nunjucks{% steamgame 1057090 "I like it." %}```{% steamgame 1057090 "I like it." %}```Nunjucks{% steamgames %}2615701057090{% endsteamgames %}
本项目不再维护,在线编辑建议使用code-server!
本插件已实现以下功能:
hexo clean
,hexo server
,hexo deploy
git pull
git add --all .
git commit -m "..."
git push
npm install hexo-online-server
新建config.json
文件, 内容如下(注释删掉):
{ "indexPath":"/",// 自定义主页路径, 以"/"结尾 "port": 4001,// http监听端口 "wsPort": 4002,//websocke监听端口 "secret":"",//用来签名session ID cookie,https://www.npmjs.com/package/express-session#secret "user":"",//登录用户名 "passwordHash": "",//密码加密后的字符串 "autoSave": 300000,//编辑文章时自动保存时间, 单位:ms, 0为不自动保存 "noticeUrl":"",//当有用户登录时向`此链接+message`发送get请求,留空则不通知 "pull":["git pull"],//从git同步命令 "push":["git add --all .","git commit -m 'Update at {time}'","git push"],//同步到git命令 "ssl":false,//是否启用SSL "private":{//启用ssl需配置此项 "key":"",//SSL证书key路径 "crt":""//SSL证书路径 }}
注意把后面的注释删掉!
把config.json
文件保存到你的博客目录以外的地方, 在_config.yml
中添加:
onlineConfigPath: '../config.json' #`config.json`文件路径
使用以下命令获取加密密码, 将得到的passwordHash
添加到config.json
文件:
> hexo bcrypt 你的密码
运行hexo online
, 浏览器打开http://localhost:4001/
从git同步
,编辑完成后同步到git
如果你使用的自动部署,直接将源码同步到 git 仓库即可,不用hexo deploy
注意,本文方法主要用于 Butterfly 主题,其他主题需要有一定的前端知识 !!!
DIY 前请先备份!!!
本文基于 Butterfly 主题 3.0.0 之前的版本修改!
3.0.0 版本之后的部分内容可能需要调整!
对前端及自己使用的主题不太了解的话建议不要随意修改!
在themes\Butterfly\layout\includes\widget
文件夹新建card_pixiv.pug
文件,文件内容如下:
.card-widget.card-pixiv .card-content .item-headline i.fa.fa-image(aria-hidden="true") span= _p('aside.card_pixiv') iframe(src="https://cloud.mokeyjay.com/pixiv" frameborder="0" style="width:99%;height:380px;margin:0;")
https://cloud.mokeyjay.com/pixiv
使用的是超能小紫提供的服务,也可以自行搭建,搭建方式请看这里
编辑themes\Butterfly\layout\includes\widget\index.pug
文件,在你想要显示的位置插入以下代码:
if theme.aside.card_pixiv include ./card_pixiv.pug
编辑butterfly.yml
文件,在card_webinfo
下面添加一行card_pixiv: true
编辑themes\Butterfly\languages\zh-CN.yml
文件(请根据你的网站语言选择),找到card_announcement: 公告
, 在下面添加一行card_pixiv: Pixiv日榜Top50
(后面的文本可自定义)
如果不想显示,直接把butterfly.yml
文件的card_pixiv: true
改为card_pixiv: false
即可
将以下内容插入到需要显示的地方:
<iframe src="https://cloud.mokeyjay.com/pixiv" frameborder="0" style="width:100%;height:380px;margin:0;"></iframe>
前往clustrmaps网站注册一个帐号
找到Free Tools
下面的Website Widget
, 点击Get Map Widget
输入你的博客网址,点击Next
根据你自己的喜好选择样式Map widget
或Globe Widget
找到如下代码,记住 src(******
的部分):
<script type="text/javascript" id="clstr_globe" src="**********************">
在themes\Butterfly\layout\includes\widget
文件夹新建card_map.pug
文件,文件内容如下:
.card-widget.card-map .card-content .item-headline i.fas.fa-globe-asia(aria-hidden="true") span= _p('aside.card_map') //- 下面这行适用于3D地图(Globe Widget) script#clstr_globe(type="text/javascript" defer="defer" src="******************") //- 下面这行适用于平面地图(Map Widget) script#clustrmaps(type="text/javascript" defer="defer" src="******************")
******
部分填写上面的 src, 3D 地图和平面地图任选一个,不用的把代码删掉
编辑themes\Butterfly\layout\includes\widget\index.pug
文件,在你想要显示的位置插入以下代码:
if theme.aside.card_map include ./card_map.pug
编辑butterfly.yml
文件,在card_webinfo
下面添加一行card_map: true
编辑themes\Butterfly\languages\zh-CN.yml
文件(请根据你的网站语言选择),找到card_announcement: 公告
, 在下面添加一行card_map: 访客地图
(后面的文本可自定义)
如果不想显示,直接把butterfly.yml
文件的card_map: true
改为card_map: false
即可
将上面第 5 步中的代码插入到需要显示的地方。
本方法只适用于 Butterfly 主题!
安装hexo-generator-calendar
插件
npm install --save git://github.com/howiefh/hexo-generator-calendar.git
下载calendar.js
和languages.js
文件,保存到themes\Butterfly\source\js
目录
编辑calendar.js
文件,在文件最后}(jQuery));
之前添加:
$(document).ready(function () { $('#calendar').aCalendar('zh-CN');//'zh-CN'请根据自己博客的语言选择});
编辑butterfly.yml
文件, 以下两个你butterfly.yml
文件里有哪个就用那个,不要都用!
CDN_USE->js
下面添加如下内容:- /js/calendar.js- /js/languages.js
inject->bottom
下面添加如下内容:- <script src="/js/calendar.js"></script>- <script src="/js/languages.js"></script>
下载calendar.styl文件,保存到themes\Butterfly\source\css\_layout
目录
在themes\Butterfly\layout\includes\widget
文件夹新建card_calendar.pug
文件,文件内容如下:
.card-widget.card-calendar .card-content .item-headline i.far.fa-calendar-alt(aria-hidden="true") span= _p('aside.card_calendar') div.widget-wrap div#calendar.widget
编辑themes\Butterfly\layout\includes\widget\index.pug
文件,在你想要显示的位置插入以下代码:
if theme.aside.card_calendar include ./card_calendar.pug
编辑butterfly.yml
文件,在card_webinfo
下面添加一行card_calendar: true
编辑themes\Butterfly\languages\zh-CN.yml
文件(请根据你的网站语言选择),找到card_announcement: 公告
, 在下面添加一行card_calendar: 文章日历
(后面的文本可自定义)
如果不想显示,直接把butterfly.yml
文件的card_calendar: true
改为card_calendar: false
即可
前往widgetpack注册账号
登陆后在点击左侧侧边栏Rating
->Install
, 你会看到如下代码,记住id
:
<div id="wpac-rating"></div><script type="text/javascript">wpac_init = window.wpac_init || [];wpac_init.push({widget: 'Rating', id: *****});(function() { if ('WIDGETPACK_LOADED' in window) return; WIDGETPACK_LOADED = true; var mc = document.createElement('script'); mc.type = 'text/javascript'; mc.async = true; mc.src = 'https://embed.widgetpack.com/widget.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(mc, s.nextSibling);})();</script><a href="https://widgetpack.com" class="wpac-cr">Star Rating WIDGET PACK</a>
在博客根目录/themes/Butterfly/layout/includes/post/
目录内新建文件rate.pug
, 内容如下:
#wpac-ratingscript. wpac_init = window.wpac_init || []; wpac_init.push({widget: 'Rating', id: #{theme.rate.id}}); (function() { if ('WIDGETPACK_LOADED' in window) return; WIDGETPACK_LOADED = true; var mc = document.createElement('script'); mc.type = 'text/javascript'; mc.async = true; mc.src = '//embed.widgetpack.com/widget.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(mc, s.nextSibling); })();style. #wpac-rating { margin-top: 20px; text-align: center; }
编辑博客根目录/themes/Butterfly/layout/post.pug
文件,在!=partial('includes/post/reward', {}, {cache:theme.fragment_cache})
下方添加:
if theme.rate.enable include includes/post/rate.pug
注意缩进if
与上面的if
对齐
在Butterfly.yml
文件内添加:
rate: enable: true id: #上面记住的id
将第 2 步生成的代码插入到需要显示的位置。
更新到最新版即可。
将以下内容添加到<head></head>
标签内:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/HCLonely/images@master/others/loading.min.css">
将以下内容添加到<body>
标签后面:
<div id="loading-box"> <div class="loading-left-bg"></div> <div class="loading-right-bg"></div> <div class="spinner-box"> <div class="configure-border-1"> <div class="configure-core"></div> </div> <div class="configure-border-2"> <div class="configure-core"></div> </div> <div class="loading-word">加载中...</div> </div></div>
将以下内容添加到</body>
标签前面:
<script> var endLoading = function () { document.body.style.overflow = 'auto'; document.getElementById('loading-box').classList.add("loaded"); } window.addEventListener('load',endLoading);</script>
编辑博客根目录/themes/Butterfly/layout/includes/footer.pug
文件,将©${theme.since} - ${nowYear} By ${config.author}
改为©${theme.since} - ${nowYear + ' '} <i id="heartbeat" class="fa fas fa-heartbeat"></i> ${config.author}
, 将©${nowYear} By ${config.author}
改为©${nowYear + ' '} <i id="heartbeat" class="fa fas fa-heartbeat"></i> ${config.author}
编辑butterfly.yml
文件, 以下两个你butterfly.yml
文件里有哪个就用那个,不要都用!
CDN_USE->css
下面添加如下内容:- https://cdn.jsdelivr.net/gh/HCLonely/images@master/others/heartbeat.min.css
inject->head
下面添加如下内容:- <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/HCLonely/images@master/others/heartbeat.min.css">
将<i id="heartbeat" class="fa fas fa-heartbeat"></i>
添加到需要显示的位置
将以下内容添加到<head></head>
标签内:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/HCLonely/images@master/others/heartbeat.min.css">
博客根目录/themes/Butterfly/layout/includes/footer.pug
文件,在最后span=theme.ICP.text
下一行添加以下内容: #running-time script. setInterval(()=>{let create_time=Math.round(new Date('2020-01-03 00:00:00').getTime()/1000);let timestamp=Math.round((new Date().getTime()+8*60*60*1000)/1000);let second=timestamp-create_time;let time=new Array(0,0,0,0,0);if(second>=365*24*3600){time[0]=parseInt(second/(365*24*3600));second%=365*24*3600;}if(second>=24*3600){time[1]=parseInt(second/(24*3600));second%=24*3600;}if(second>=3600){time[2]=parseInt(second/3600);second%=3600;}if(second>=60){time[3]=parseInt(second/60);second%=60;}if(second>0){time[4]=second;}currentTimeHtml='本站已安全运行 '+time[0]+' 年 '+time[1]+' 天 '+time[2]+' 时 '+time[3]+' 分 '+time[4]+' 秒';document.getElementById("running-time").innerHTML=currentTimeHtml;},1000);
注意#running-time
与上面的if theme.ICP.enable
对齐!
要将2020-01-03 00:00:00
改为你网站的起始时间!
<div id="running-time"></div><script>setInterval(()=>{let create_time=Math.round(new Date('2020-01-03 00:00:00').getTime()/1000);let timestamp=Math.round((new Date().getTime()+8*60*60*1000)/1000);let second=timestamp-create_time;let time=new Array(0,0,0,0,0);if(second>=365*24*3600){time[0]=parseInt(second/(365*24*3600));second%=365*24*3600;}if(second>=24*3600){time[1]=parseInt(second/(24*3600));second%=24*3600;}if(second>=3600){time[2]=parseInt(second/3600);second%=3600;}if(second>=60){time[3]=parseInt(second/60);second%=60;}if(second>0){time[4]=second;}currentTimeHtml='本站已安全运行 '+time[0]+' 年 '+time[1]+' 天 '+time[2]+' 时 '+time[3]+' 分 '+time[4]+' 秒';document.getElementById("running-time").innerHTML=currentTimeHtml;},1000);</script>
要将2020-01-03 00:00:00
改为你网站的起始时间!
此方法只适用于 Butterfly 主题!
这里以同时使用Valine
和Gitalk
, 默认使用Valine
为例。
请确认Valine
和Gitalk
已开启并正确配置。
修改themes/Butterfly/layout/includes/comments/index.pug
文件,将所有的else if
改为if
, 并在span= ' ' + _p('comment')
下面添加:
a#switch-comment(href="javascript:void(0);" title="切换为Gitalk" target="_self") i.fa.fas.fa-toggle-off(aria-hidden="true")
隐藏一个评论,保留一个默认评论
valine
: 修改themes/Butterfly/layout/includes/comments/valine.pug
文件,在#vcomment.vcomment
后面添加(style=‘display:none;’)gitalk
: 修改themes/Butterfly/layout/includes/comments/gitalk.pug
文件,在#gitalk-container
后面添加(style=‘display:none;’)在themes/Butterfly/source/js/third-party/
目录新建switch_comments.js
文件,内容如下:
$('#switch-comment').click(function () { switchComment() return false})function switchComment () { const title = $('#switch-comment').attr('title') === '切换为Gitalk' ? '切换为Valine' : '切换为Gitalk' const i = $('#switch-comment>i') if ($('#gitalk-container').css('display') === 'none') { $('#vcomment').slideUp('normal', () => { $('#gitalk-container').slideDown('normal', () => { $('#switch-comment').attr('title', title) i.hasClass('fa-toggle-off') ? i.removeClass('fa-toggle-off').addClass('fa-toggle-on') : i.removeClass('fa-toggle-on').addClass('fa-toggle-off') }) }) } else { $('#gitalk-container').slideUp('normal', () => { $('#vcomment').slideDown('normal', () => { $('#switch-comment').attr('title', title) i.hasClass('fa-toggle-off') ? i.removeClass('fa-toggle-off').addClass('fa-toggle-on') : i.removeClass('fa-toggle-on').addClass('fa-toggle-off') }) }) }}
编辑butterfly.yml
文件, 以下两个你butterfly.yml
文件里有哪个就用那个,不要都用!
CDN_USE->js
下面添加如下内容:- /js/third-party/switch_comments.js
inject->bottom
下面添加如下内容:- <script src="/js/third-party/switch_comments.js"></script>
如果你使用的其他评论系统注意替换上面的切换为Gitalk
, 切换为Valine
, #gitalk-container
, #vcomment
切换图标使用的fontawesome
, 兼容V4
和V5
, 如果你是用的其他图标库,请替换fa-toggle-on
和fa-toggle-off
在博客根目录/scripts
(没有请自行创建)下新建random.js
文件,内容如下:
hexo.extend.generator.register('random', function (locals) { const config = hexo.config.random || {} const posts = [] for (const post of locals.posts.data) { if (post.random !== false) posts.push(post.path) } return { path: config.path || 'random/index.html', data: `<html><head><script>var posts=${JSON.stringify(posts)};window.open('/'+posts[Math.floor(Math.random() * posts.length)],"_self")</script></head></html>` }})
打开/random/
就会随机跳转一篇文章
可选配置
可以在_config.yml
添加以下配置:
random: path: # 随机链接路径,默认"random/index.html"
如果不想随机跳转到某篇文章,只需在这篇文章Front-matter
添加random: false
从matery 主题上看到了文章发布统计图
、标签统计图
和文章分类统计图
,觉得挺好看,就扒下来做了个插件。
因为使用 Tag 会导致文章获取不全,所以本插件直接使用 html 标签渲染,而不是使用 Tag。由于使用了 cheerio 模块,如果你使用了 html 压缩插件,可能会出现压缩报错,暂时无解。
npm install hexo-charts -S
注意!下面的标签可以放到post
和不含type
的page
的md
文件中,含有type
的page
请自行修改相应的模板文件,这个就不要来问我了,因为每个人用的主题可能都不一样,建议去问主题的作者。
<div id="posts-chart"></div>
<!-- "data-length"为显示标签个数(从多到少),默认为10 --><div id="tags-chart" data-length="10"></div>
<div id="categories-chart"></div>
在主题目录/Butterfly/layout/archive.pug
文件的#archive
下面添加一行#posts-chart
, 新添加的比上一行多缩进两个空格。
block content include ./includes/mixins/article-sort.pug #archive #posts-chart
主题目录/Butterfly/layout/page.pug
文件,在.tag-cloud
下面添加一行#tags-chart
,在.category-content
下面添加一行#categories-chart
,新添加的比上一行多缩进两个空格。block content if page.type === 'tags' .tag-cloud #tags-chart
else if page.type === 'categories' .category-content #categories-chart
npm install hexo-helper-qrcode -S
主题目录/Butterfly/layout/includes/header/post-info.pug
, 在文件最后添加以下内容: span.post-qrcode span.post-meta__separator | i.fa.fa-qrcode.post-meta__icon.fa-fw(aria-hidden="true") a(href="javasvript:;" onmouseover='document.getElementById("post-qrcode").style.display="block"' onmouseout='document.getElementById("post-qrcode").style.display="none"')='二维码' div#post-qrcode.post-qrcode-img img#post-img(src=qrcode(page.permalink))
注意span.post-qrcode
要与上面的span.post-meta-commentcount
对齐!
以下内容仅适用于 Butterfly 主题 <= V2.3.5,其他主题可以根据本教程和这篇文章自行修改!
Butterfly 主题 >= V4.0 请往下翻!
下载valine.pug文件,替换themes/Butterfly/layout/includes/comments/valine.pug
编辑butterfly.yml
文件,找到valine
配置,添加以下配置项:
master: # md5加密后的博主邮箱 - f8c7c3961aea2c203160e90cd3b3a26a friends: # md5加密后的小伙伴邮箱 - 5c2105bbfe6rfc02a6f6ae26dad3819c - a0adabb31677df92a2405fb18a02ee4d metaPlaceholder: # 输入框的背景文字 nick: 昵称/QQ号(必填) mail: 邮箱(必填) link: 网址(https://) tagMeta: '博主,小伙伴,访客' # 标签要显示的文字,默认'博主,小伙伴,访客' verify: false # 评论时是否需要验证,需jQuery支持
编辑butterfly.yml
文件,将CDN
中的valine
链接改为https://cdn.jsdelivr.net/gh/HCLonely/Valine@latest/dist/Valine.min.js
改完之后hexo clean
一下,不然不会生效
以下内容仅适用于 Butterfly 主题 >= V4.0!
butterfly.yml
文件,找到valine
配置,在option
下添加以下配置项(注意缩进!): option: master: # md5加密后的博主邮箱 - f8c7c3961aea2c203160e90cd3b3a26a friends: # md5加密后的小伙伴邮箱 - 5c2105bbfe6rfc02a6f6ae26dad3819c - a0adabb31677df92a2405fb18a02ee4d metaPlaceholder: # 输入框的背景文字 nick: 昵称/QQ号(必填) mail: 邮箱(必填) link: 网址(https://) tagMeta: # 标签要显示的文字,请注意顺序! - 博主 - 小伙伴 - 访客
编辑butterfly.yml
文件,将CDN
中的valine
链接改为https://cdn.jsdelivr.net/gh/HCLonely/Valine@latest/dist/Valine.min.js
改完之后hexo clean
一下,不然不会生效
为了避免每次找模块时都要百度,这里记一下我比较常用的模块及其简单的使用。
cheerio是 jquery 核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对 DOM 进行操作的地方。
npm install cheerio
const cheerio = require('cheerio'),$ = cheerio.load('<html><body>Hello, <b>world</b>!</body></html>');
axios-https-proxy-fix是修复axios代理 https 失败的分支版本。
npm install axios-https-proxy-fix
moment 是一个 JavaScript 日期处理类库,用于解析、检验、操作、以及显示日期。
npm install moment
const moment = require('moment '),moment().format('YYYY-MM-DD HH:mm:ss');
Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。
npm install lodash
ali-oss 是使用 NodeJs 操作阿里云 OSS 官方模块。
npm install ali-oss
Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。
npm i puppeteer
nrm(npm registry manager )是 npm 的镜像源管理工具,有时候国外资源太慢,使用这个就可以快速地在 npm 源间切换。
npm install -g nrm
> nrm ls* npm -------- https://registry.npmjs.org/ yarn ------- https://registry.yarnpkg.com/ cnpm ------- http://r.cnpmjs.org/ taobao ----- https://registry.npm.taobao.org/ nj --------- https://registry.nodejitsu.com/ npmMirror -- https://skimdb.npmjs.com/registry/ edunpm ----- http://registry.enpmjs.org/
> nrm use taobao Registry has been set to: https://registry.npm.taobao.org/
]]>为 Hexo 添加 Steam 游戏库页面
注意,本插件会和hexo s
命令冲突,请使用hexo se
或hexo server
代替hexo s
命令!
$ npm install hexo-steam-games --save
$ npm install hexo-steam-games --update --save
将下面的配置写入站点的配置文件 _config.yml
里(不是主题的配置文件).
steam: enable: true steamId: '*****' #steam 64位Id path: title: Steam游戏库 quote: '+1+1+1+1+1' tab: recent length: 1000 imgUrl: '*****' proxy: host: port:
steamgames/index.html
all
或recent
, all: 所有游戏
, recent: 最近游玩的游戏
quote
下面放一张图片,图片链接到 Steam 个人资料,可留空hexo generate
或hexo deploy
之前使用hexo steam -u
命令更新 steam 游戏库数据!hexo steam -d
如果hexo steam -u
命令一直获取游戏库数据失败,可以用以下方法手动获取游戏库数据:
浏览器打开https://steamcommunity.com/profiles/{steamId}/games?tab={tab}
, {steamId}
和{tab}
分别替换为上面配置中提到的steamId
和tab
网页加载完成后,打开浏览器控制台(按F12
),输入以下代码并回车:
let script = jQuery('script[language="javascript"]');var games = [];for (let i = 0; i < script.length; i++) { if (script.eq(i).html().includes("rgGames")) { let rgGames = script.eq(i).html().match(/var.*?rgGames.*?=.*?(\[[\w\W]*?\}\}\]);/); if (rgGames) { games = JSON.parse(rgGames[1]); break; } }}document.write(JSON.stringify(games))
将生成的内容复制到博客根目录/node_modules/hexo-steam-games/data/games.json
文件内,如果没有对应的文件或目录,请自行创建