Hexo折腾史
推荐博客
搭建Hexo
全局安装hexo命令
初始化Hexo
hexo init
安装主题(两种方式)
git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly
把主题放置在主目录中,更容易定制主题
npm i hexo-theme-butterfly
虽然配置容易,但主题会放在node_modules中,定制主题不方便
本地部署(本地测试)
hexo server
远程仓库配置
新建Github远程仓库
git push -u origin main
部署到Github
两种方式都可以,可以只用一种,也可以都用
不需要push,可以单独deploy
这样部署不仅方便,而且就不需要push源文件到main分支就可以查看效果(避免过多提交代码)
npm i hexo-deployer-git
修改_config.yml配置
1 2 3 4 deploy: type: git repo: https://github.com/<username>/<project> branch: gh-pages
hexo clean && hexo deploy
源文件在main分支中,部署生成的静态文件在gh-pages分支中
Github Actions配置workflow,push后通过自动部署
这个方式对于特定情形非常有用:电脑不在身边,只用手机端修改很少的代码,push即可自动部署
添加.github/workflows/main.yml
文件,填入如下内容(注意node版本):
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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 name: Push部署 on: push: branches: - main workflow_dispatch: jobs: deploy: runs-on: ubuntu-latest steps: - name: 检查分支 uses: actions/checkout@v2 with: ref: main fetch-depth: 0 - name: 安装 Node uses: actions/setup-node@v1 with: node-version: "16.x" - name: 设置时区 run: sudo timedatectl set-timezone 'Asia/Shanghai' - name: 安装 Hexo run: | npm install hexo-cli -g - name: 缓存 Hexo id: cache-npm uses: actions/cache@v3 env: cache-name: cache-node-modules with: path: node_modules key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - name: 安装依赖 if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }} run: | npm install --save - name: 修改post文件时间 run: | find source/_posts -name '*.md' | while read file; do touch -d "$(git log -1 --format="@%ct" "$file")" "$file"; done - name: 生成静态文件 run: | hexo clean hexo generate hexo algolia - name: 部署到Github uses: JamesIves/github-pages-deploy-action@v4 with: repository-name: BUGHERE/bughere.github.io branch: gh-pages folder: public commit-message: "${{ github.event.head_commit.message }} Updated By Github Actions"
因为Github Page
静态文件在gh-pages
分支中,所以在Github
设置Github Page
分支:Settings
-Pages
-Source
其中遇到了更新时间错误问题【配置文件已解决】:在使用 Github Actions 自动化部署 hexo 博客时会发现所有文章的更新时间都变成了此次提交修改的时间,但实际上这些文章是没有任何修改的。参考文献:修复 CI 构建博客造成的更新时间错误 ,0o酱详细版
一些语法
关于Hexo的分类和标签
只有文章支持分类和标签,您可以在 Front-matter 中设置。在其他系统中,分类和标签听起来很接近,但是在 Hexo 中两者有着明显的差别:分类具有顺序性和层次性,也就是说 Foo, Bar 不等于 Bar, Foo;而标签没有顺序和层次。
1 2 3 4 5 categories: - Diary tags: - PS3 - Games
子分类
下面的设置会使分类 Life
成为 Diary
的子分类,而不是并列分类。因此,有必要为您的文章选择尽可能准确的分类
1 2 3 categories: - Diary - Life
为文章添加多个分类
此时这篇文章同时包括三个分类: PlayStation
和 Games
分别都是父分类 Diary
的子分类,同时 Life
是一个没有子分类的分类。
1 2 3 4 categories: - [Diary , PlayStation ]- [Diary , Games ]- [Life ]
Katex
局部使用Katex:使用Katex记得在每个post的Front-matter中填写katex: true
,确保开启katex语法
全局使用Katex:在_config.butterfly.yml中:
标签外挂
使用mermaid绘制图标
graph LR
subgraph 1
direction LR
a(workspace) --add--> b(index) --commit--> c(repository) --push--> d(remote)
d --pull--> a
d --clone--> c
c --checkout--> a
end
subgraph 2
a(workspace) --stash --> e(stash)
e -- stash pop --> a
end
1 2 3 4 5 6 7 8 9 10 11 12 13 14 {% mermaid %} graph LR subgraph 1 direction LR a(workspace) --add--> b(index) --commit--> c(repository) --push--> d(remote) d --pull--> a d --clone--> c c --checkout--> a end subgraph 2 a(workspace) --stash --> e(stash) e -- stash pop --> a end {% endmermaid %}
在线编辑网站:链接
tabs
Butterfly官方教程
hideToggle
隐藏收纳一部分文章内容
Butterfly官方教程 中的Toggle
更多功能DIY
修改配置后,查看博客可能并不会立刻看到相关功能,甚至可能会有些错误。这个原因可能是浏览器缓存,加载了原来的渲染,这时候可以清除缓存或者使用其它浏览器和设备查看博客,或者静候一段时间。
Chrome 清除某个特定网站下的缓存:打开开发者工具(F12),选择 Network——Disable cache 即可。需要清除某网站缓存时 F12 打开开发者工具就会自动清除这个网站的缓存,而不必清除所有网站的缓存了。
关于使用hexo server调试代码时,对于source里的博客内容修改,不需要重新运行hexo server命令。但如果是修改主题里的内容,比如修改_config.butterfly.yml配置,则需要重新运行hexo server命令
自定义css和js文件
参考Hexo博客添加自定义css和js文件
接入Algolia搜索功能
参考Hexo + Butterfly 键入搜索功能
注册Algolia 账号
在"Data Resources→Indices"中新建索引
执行npm install hexo-algoliasearch
查看API Key信息,“左下角Settings→Team and Access→API Keys”
修改_config.yml配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 algolia: appId: "***" apiKey: "***" adminApiKey: "***" chunkSize: 5000 indexName: "blog" fields: - content:strip - excerpt:strip - gallery - permalink - photos - slug - tags - title
执行hexo algolia
更新Algolia索引
DIY加载动画
pug代码格式是html的简化,为了是通过更简洁的代码生成对应的html代码。
而styl格式也是类似的,为了用更简洁的代码生成对应的css代码
有时候加载太快了,看不到加载动画。这时为了看到加载动画,我们可以手动调整浏览器的网速,打开F12-网络,在菜单栏找到默认的”No throttling“字样(不节流),改成”Slow 3G“就可以了
参考Akilar
主要调整了程序配置入口的代码,以及用到的两种文件:pug
和styl
,分别对应html
和css
文件
pug资源目录:themes/butterfly/layout/includes/loading/load_style
styl资源目录:themes/butterfly/source/css/_load_style
pug
的配置入口位置:themes/butterfly/layout/includes/loading/fullpage-loading.pug
styl
的配置入口位置:themes/butterfly/source/css/_layout/loading.styl
后续增加新的加载动画也只要在这些地方修改:(1)资源目录添加资源(2)配置入口增加配置
需要注意Butterfly版本,版本更新后,文件结构有所调整
4.10
版本的fullpage-loading.pug
文件大概如下:
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 28 29 30 31 32 33 34 35 36 37 38 if theme.preloader.enable case theme.preloader.load_style when 'gear' include ./load_style/gear.pug when 'scarecrow' include ./load_style/scarecrow.pug when 'image' include ./load_style/image.pug when 'spincat' include ./load_style/spincat.pug default include ./load_style/default.pug script(async). (()=>{ const $loadingBox = document.getElementById('loading-box') const $body = document.body const preloader = { endLoading: () => { $body.style.overflow = '' $loadingBox.classList.add('loaded') }, initLoading: () => { $body.style.overflow = 'hidden' $loadingBox.classList.remove('loaded') } } preloader.initLoading() window.addEventListener('load',() => { preloader.endLoading() }) setTimeout(function(){preloader.endLoading();}, 5000); // 超时关闭动画 $loadingBox.addEventListener('click',()=> {preloader.endLoading()}) // 点击关闭动画 if (!{theme.pjax && theme.pjax.enable}) { document.addEventListener('pjax:send', () => { preloader.initLoading() }) document.addEventListener('pjax:complete', () => { preloader.endLoading() }) } })()
接入Twikoo评论
用Vercel+MongoDB免费部署
Twikoo备份
用国内域名加速Vercel
置顶和隐藏文章【已弃用】
0o酱的hexo-generator-index-custom插件
随机跳转文章
Hexo的Butterfly魔改教程:随机网页跳转(无缝版)
首页顶部文章轮播图【已弃用】
教程:hexo-swiper 文章置顶插件
首页顶部轮播图和文章推荐卡片
【Hexo博客 | 如何为博客添加顶部轮播图和文章推荐卡片】(https://blog.justlovesmile.top/posts/6a0d6454.html )
轮播图内容修改:themes\butterfly\layout\includes\sticky.pug
轮播图底部分类内容修改:themes\butterfly\layout\includes\hometop.pug
文章推荐卡片内容修改:source_data\slider.yml(不知道为什么叫slider)
分类条
展示在首页和分类页
修改分类:themes\butterfly\layout\includes\categoryBar.pug
Butterfly魔改:动态分类条,可以根据页面变化而改变的分类列表展示方式
由于它这里js写的是直接按照url划分’/',得到最后一个元素,当作分类,所以这里不支持子分类,所以我这里的分类条的高亮不是动态跟随的
由于本站设置了category_ui: index # 留空或 index
,分类页的post ui和主页post ui是一样的
所以这里category.pug需要写在这里
1 2 3 4 5 6 if theme.category_ui == 'index' include ./includes/mixins/post-ui.pug #recent-posts.recent-posts.category_ui include includes/categoryBar.pug +postUI include includes/pagination.pug
说说和清单页面
使用Memos【已弃用】
Memos Github地址
可以找到api目录的yaml文件
通过swagger editor 就可以查看api文档了
后端部署
Zeabur部署【已弃用】 后端Replit部署【已弃用】 zeabur市场上提供好的memos模板,可以点击即用,但是这个需要付费
fork一份memos官方GitHub仓库到自己仓库,部署上去即可
但考虑到zeabur需要7天登陆上去手动续期,于是不用zeabur了
参考九弦
免费用户的replit仓库只能设置public,所以不要写一些过于私密的内容。对我来说,够用了
好像也可以用Railway部署,没试过,不知道咋样
后续,2024年1月,replit域名失效了,查看replit推文 ,如下所示
On January 1st, 2024, repl.co domains will transition to replit.dev and will only be accessible when someone is in the editor. If you are currently “hosting” anything on repl.co , we strongly recommend that you migrate to Deployments before the new year.
说是不提供免费的repl.co域名了,只提供replit.dev域名,并且需要有人在editor页面
现在的replit.dev域名又臭又长,像这样:https://66b4d66d-5794-4c83-9907-5519995b7d8e-00-15cwgy9gwbwnv.pike.replit.dev/
我寻思绑定个自己的域名呗,结果也是这次的更新把免费部署的绑定域名功能取消了,参考这篇帖子 ,主要内容如下:
Welcome to Ask @Coconutf! The reason that traditional custom domain linking on Replit was removed is because traditional repl.co hosting is being removed from Replit. It has been replaced by deployments 1 (replit.app). You can link a custom domain to deployments. Repls require a paid plan/connected credit card to host but will still be able to have custom domains (so long as the repl hosts a website).
害,replit不香了
前端部署参考哔哔点啥 2.0 By Memos
用这个实现说说和清单功能,舒服了,舒服了
可以把大佬云端的bb-lmm-mk.js
文件放到本地加载,这样就可以编辑自定义功能了。比如,我就在memos请求url中加了一个tag属性,对说说和清单页面分别获取memos内容。
静态部署(前端+后端)【使用中】
思来想去,白嫖党还是不整这些东西了吧。整半天,到时候又收费了,难搞。
自己折腾半天瀑布流,才发现icat大佬已经弄好啦
直接弄个静态部署的说说页面,参考Butterfly的魔改教程:即刻短文页 以及大佬的颜色
清单页面参考Butterfly的魔改教程:待办清单
大佬整理了自己的颜色和图标,我们无法直接使用
对于颜色部分,我直接用了大佬的颜色配置 ;图标部分,我用fontawesome图标替换了大佬的图标,修改essay.pug
文件如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .icat-bber-bottom .icat-bber-info .icat-bber-info-time - var datedata = new Date(item.date).toISOString() <i class="fa-regular fa-clock"></i> time.datatime(datetime= item.date)= datedata if item.link a.icat-bber-content-link(target="_blank", title="跳转到短文指引的链接", href=item.link, rel="external nofollow") <i class="fa-solid fa-link"></i> | 链接 if item.from .icat-bber-info-from <i class="fa-solid fa-location-dot"></i> span=item.from .icat-bber-reply(onclick="icatessay.commentText(" + `'${item.content}'` + ")") <i class="fa-regular fa-message"></i>
我没有打开pjax,感觉没必要
其次,如果要使用快速评论功能的话,需要在配置文件中关闭评论功能的懒加载,否则无法跳转到评论区域,具体原因如下所示。其中,因为没有加载出评论区,所以变量n为空,无法执行后续逻辑
1 2 3 4 5 6 commentText : function (e ) { if (e == "undefined" || e == "null" ) e = "好棒!" ; var n = document .getElementsByClassName ("el-textarea__inner" )[0 ], t = document .createEvent ("HTMLEvents" ); if (!n) return ; ...
顺便一提,如果用memos动态部署,而memos加载太慢的话,会导致视窗height=0。需要修改essay_page.css的代码,调整加载瀑布流的作用时间:
1 2 3 4 5 6 7 reflashEssayWaterFall : function ( ) { document .querySelector ("#waterfall" ) && setTimeout (function ( ) { waterfall ("#waterfall" ); document .getElementById ("waterfall" ).classList .add ("show" ); }, 1000 ); },
这个部署方式用了很多inject,后面看下有没办法优化下
友链
参考Butterfly官方文档
藏宝阁
参考博客
实现后,我发现我还是更喜欢他的作品推荐卡片 的样式
于是进行了小小的修改:
collect.pug
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 28 29 30 31 32 33 34 #article-container .collect - let collectPageContent = page.content if site.data.collect - let result = "" each i in site.data.collect - let className = i.class_name ? `<h2 ${i.class_desc?'':'style="margin-bottom:12px"'}>${i.class_name} (${i.link_list.length})</h2>` : "" - let classDesc = i.class_desc ? `<div class="collect-desc">${i.class_desc}</div>` : "" - let listResult = "" each j in i.link_list - let background = j.img ? `background-image: url(${j.img});` : 'background-color: #cfd9df;' - let w = j.width || '150px' - let h = j.height || '200px' - listResult += ` <div title="${j.name}" referrerPolicy="no-referrer" class="collect_box" style="${background} width:${w}; height:${h};"> <div class="collect_mask"> <span>${j.text ? j.text : ''}</span> ${j.url?'<a href="' + j.url + '">查看详情</a>' : ''} </div> <div class="collect_top"> <i class="${j.icon?j.icon:'fa-solid fa-film'}"></i> <span>${j.tip?j.tip:''}</span> </div> <div class="collect_content"> <span>${j.name?j.name:'未知'}</span> <div>${j.score?toStar(j.score):toStar(0)}</div> </div> </div> ` - - result += `${className}${classDesc} <div class="collect-list">${listResult}</div>` - collectPageContent = collectPageContent + result != collectPageContent
collect.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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 .collect h2 margin-bottom : 0 .collect-desc margin-bottom : 10px .collect-list display : flex gap : 18px flex-wrap : wrap .collect_box display : flex justify-content : space-between flex-direction : column background-position : center background-size : cover border-radius : 12px position : relative overflow : hidden padding : 10px color : #fff !important &::after content : '' position : absolute height : 100% width : 100% left : 0 top : 0 background : rgba (0 ,0 ,0 ,0.1 ) transition : .5s z-index : 0 &:hover .collect_mask opacity : 1 pointer-events : auto .collect_top display : flex z-index : 1 align-items : center justify-content : space-between .collect_mask position : absolute pointer-events : none z-index : 2 transition : .5s opacity : 0 width : 100% height : 100% left : 0 top : 0 padding : 20px background : #333 span display : block height : calc (100% - 40px ) overflow : auto a text-align : center background : #fff color : #333 !important border-radius : 5px position : absolute width : calc (100% - 40px ) bottom : 20px left : 20px &:hover text-decoration : none !important color : white !important background : #49b1f5 .collect_content z-index : 1 span font-size : 18px font-weight : bold [data-theme='dark' ] .collect .collect-list .collect_box color : #ddd !important &:hover &::after background : rgba (0 ,0 ,0 ,0.2 ) &::after background : rgba (0 ,0 ,0 ,0.5 ) .collect .collect-list @media screen and (max-width : 1100px ) gap: 15px .collect_box --w: calc(20% - 12px ) @media screen and (max-width : 900px ) gap: 16px .collect_box --w: calc(25% - 12px ) @media screen and (max-width : 768px ) gap: 15px .collect_box --w: calc(100% / 3 - 10px ) @media screen and (max-width : 500px ) gap: 16px .collect_box --w: calc(50% - 8px )
语雀同款链接卡片
参考:语雀同款链接卡片
语法:
1 2 3 4 5 6 * {% link url ,title ,favicon ,desc % } * {% link 链接 ,标题 ,图标 ,介绍 % } * {% link 链接 ,标题 , ,介绍 % } {% link https://bughere.github.io/solution/blog/solution-blog-loading-animation-love-death-robots/ , 爱死机加载动画 , https://bughere.github.io/img/favicon/BHE.png , 自己做的一个动画 % }
图床
采用 GitHub + jsd + PicGo
的方式部署
参考使用Github+picGo搭建图床,保姆级教程来了
文中使用typora插件,但我现在vscode用的多,所以我选择vscode插件:PicGo
其实就是,Github提供仓库,只要把图片push放进去就行了,用不用picGo都无所谓,picGo就是一个帮忙push的可视化插件
用的话,用这个加速:https://cdn.jsdelivr.net/gh/BUGHERE/BlogImages@main/collect/fan/240106-01.jpg