Hexo+Github 博客 butterfly 主题 搭建过程【整理】
仅是记录一下搭建过程,方便自己后期维护与主题升级。一定要写一点功能就跑一边代码,我后面找不见报错真的令人头大!最好用webstorm这类可以历史回滚的编译器
本篇搭建记录基于2023年06月06日发布的butterfly 4.9.0,教程可能会滞后,以最新版本为准
一、前期准备 Node.js 官网 :让JAVAscript成为与PHP、Python、Perl、Ruby等服务器语言平起平坐的脚本语言Git 官网 :开源分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理注册一个GitHub账号 ,专门找了一篇含报错及解决办法的,注册名、密码、邮箱记好这个时候可能有小伙伴要说了,这都是啥呢怎么都是汉字组在一起又看不懂了?我没学过JAVAscript,我电脑貌似装过但是不记得了…没关系!本篇从小白讲起!
两个软件安装完之后或不记得有没有,win +R 输入cmd打开命令行窗口,依次输入三条命令
node -v npm -v git --version
如果和我的一样显示出来版本号,那就是之前安装过,如果没有安装过,去官网下载安装包傻瓜式安装即可(C盘小的同学记得换盘符!)
C:\Users\86158 >node -v v14.15.1 C:\Users\86158 >npm -v 6.14 .8 C:\Users\86158 >git --version git version 2.34 .1 .windows.1
接着在命令行中安装Hexo(警告WARN不影响)
同样检查一下安装成功了没有,运行命令会弹出来好多版本号就是成功了
第一次下载git需要配置,任意一个地方右击→Git Brush Here
git config --global user.name GC-ZF #名称 git config --global user.email 1310446718@qq.com #邮箱
二、配置仓库 2.1 新建仓库 为什么要注册一个GitHub,建一个仓库?我们要利用Github作为服务器去存储我们的内容,以便别人去访问
新建一个仓库,注意为了让别人可以访问到仓库的名字一定一定是注册名.github.io
2.2 关联仓库 接下来将Github与电脑进行绑定。每次把文件上传到仓库需要登录,十分麻烦,所以利用ssh就起到一个记住密码的作用,一劳永逸
在任意文件夹右击鼠标→Git Bash Here,输完命令连续按三次回车
ssh-keygen -t rsa -C "用户名" -f "id_rsa_github"
执行完命令后 C:\Users\用户名\.ssh 下多了俩文件,生成的id_rsa_github.pub以记事本打开,ctrl +A 全选并ctrl +C 复制文本内容,将公钥添加到github中,Title自定义
检查是否绑定成功,注意区分大小写!输入yes弹出Hi 用户名!才算成功
三、本地博客 现在就要开始制作我们的博客啦!既然博客要放在我们的电脑本地,自己选一个合适的地方新建文件夹,我新建一个Blog,在Blog文件夹中右击鼠标→Git Bash Here,输入(Hexo帮咱们搭好的框架,拿着直接用就行了,关于美化第四点有)
文件夹说明
node_modules: 依赖包 public:存放生成的页面(由hexo g生成) scaffolds:生成文章的一些模板 source:用来存放你的文章 themes:主题 _config.yml: 博客的配置文件 之后启动服务器,并在浏览器网址输入localhost:4000
localhost:4000是本地网络,互联网并访问不到,这里我们只是测试一下,ctrl +C 关闭本地服务器
四、发布博客到互联网 配置Github仓库 博客根目录\_config.yml(配置文件),打开方式随便一个编译器都可以,最下面修改deploy,注意一定是英文冒号,并且冒号后跟一个空格 ,repository地址在GitHub中
deploy: type : git repository: https://github.com/GC-ZF/GC-ZF.github.io.git branch: main
这个时候需要先安装deploy-git ,也就是部署的命令,这样你才能用命令部署到GitHub
npm install hexo-deployer-git --save
生成网站静态文件到 public 文件夹
上传本地文件到仓库,如果出现FATAL是网络问题,开个梯子之类
现在我们就可以在任意网络下在浏览器访问用户名.github.io了
发布文章 首先使用命令新建.md的文件,两个命令二选一(不支持手动新建)
博客根目录\source\_posts下找到新建的文件,发现他已经帮我们写入了一些东西,默认模板修改博客根目录\source\scaffolds\post)
title: {{ title }}date: {{ date }}top_img: 'https://picsum.photos/seed/picsum/1920/942' cover: 'https://picsum.photos/seed/picsum/470/315' tags: categories: toc_number: updated: keywords: description: sticky:
写好之后,依次执行
这里小补充一下,因为大部分同学既然有搭博客的想法那应该都知道markdown,没有markdown编辑器的同学,推荐Typora 官方中文站 ,关于markdown语法 网上也大把大把
五、安装并配置Butterfly 主题 第五步可以直接看卷二兔的视频教程 哔哩哔哩 ,已经足够详细,有些小白可能在读Butterfly的文档时有很多疑惑,以下是我自己CV文档+整理的配置流程
上面一二三四步,终于来到了美化!hexo给咱们写好了一堆框架,给咱们了好多衣服裤子,怎么穿的好看就看咱们怎么搭配了,这里以hexo-theme-butterfly为模板为例子,以下三个链接是官方文档、仓库,咱们直接跟着文档走(至于为什么用这个取决于@超逸学长 ,我就是看了他的博客才有了搭博客的想法,而且他有一些的魔改步骤,如果没学过html基础,一定要仔仔细细跟着他的魔改走)
更换主题 在Hexo(我之前建的Blog)目录下,右击→Git Brash Here
git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly
修改 博客根目录\_config.yml
安装依赖
npm install hexo-renderer-pug hexo-renderer-stylus --save
依次执行,hexo clean hexo g hexo s三件套部署本地,每次改完yml配置文件都需要重新运行
升级建议 主题升级会覆盖博客根目录\them\butterfly\_config.yml,为了減少升级主题带来的不便,把博客根目录theme\butterfly\_config.yml 复制到 博客根目录 下,重命名为_config.butterfly.yml
设置个人资料 博客根目录\_config.yml
title: 张时贰 subtitle: '小张同学' description: '环转码,热爱敲代码的小张!' keywords: 博客,张时贰 author: 张时贰 language: zh-CN timezone: 'Asia/Shanghai'
标签页
为我们的博客文章添加标签页(导航栏的标签按钮)
生成source/tags/index.md,title自定义。访问http://localhost:4000/tags/即可看到效果
--- title: 标签页 date: 2022-04-29 18:08:39 type: "tags" top_img: 'https://picsum.photos/1920/942' ---
分类页 为我们的博客文章添加分类页(导航栏的分类/归档按钮)
生成source/categories/index.md,title自定义。访问http://localhost:4000/categories/即可看到效果
--- title: categories date: 2022-04-29 18:16:23 type: "categories" top_img: 'https://picsum.photos/1920/942' ---
友情连接 添加友情链接
生成source/link/index.md,title自定义,访问http://localhost:4000/link/即可看到效果
--- title: link date: 2022-04-29 18:22:47 type: "link" top_img: 'https://picsum.photos/1920/942' ---
在Hexo博客目录中的source/_data(如果没有 _data 文件夹,请自行创建),创建一个文件link.yml,或者直接写到source/link/index.md
- class_name: 友情链接 class_desc: 那些人,那些事 link_list: - name: Hexo link: https://hexo.io/zh-tw/ avatar: https://d33wubrfki0l68.cloudfront.net/6657ba50e702d84afb32fe846bed54fba1a77add/827ae/logo.svg descr: 快速、简单且强大的网誌框架 - class_name: 网站 class_desc: 值得推荐的网站 link_list: - name: Youtube link: https://www.youtube.com/ avatar: https://i.loli.net/2020/05/14/9ZkGg8v3azHJfM1.png descr: 视频网站 - name: Weibo link: https://www.weibo.com/ avatar: https://i.loli.net/2020/05/14/TLJBum386vcnI1P.png descr: 中国最大社交分享平台 - name: Twitter link: https://twitter.com/ avatar: https://i.loli.net/2020/05/14/5VyHPQqR6LWF39a.png descr: 社交分享平台
主题支持友情链接随机排序,只需要在顶部 front-matter 添加 random: true
404 修改主题配置文件_config.butterfly.yml,开启404界面,同样访问http://localhost:4000/404
error_404: enable: true subtitle: '小张的页面丢啦' background:
替换文章中无法显示的图片
error_img: flink: /Hexo_img/friend_404.gif post_page: /Hexo_img/404.jpg
以下是Butterfly 安裝文檔(三) 主題配置-1 | Butterfly
导航菜单 修改主题配置文件_config.butterfly.yml,先后顺序、中文命名自由设置
格式:/路径/ || 图标,图标可留空
menu: 主页: / || fas fa-home 阅读排行: /hot-article/ || fa-solid fa-book-bookmark 文章||fa-solid fa-pencil: 时间轴: /archives/ || fas fa-archive 标签: /tags/ || fas fa-tags 分类: /categories/ || fas fa-folder-open 友链||fas fa-list: 友人帐: /link/ || fas fa-link 朋友圈: /fcircle/ || fa-solid fa-user-group 我的||fa-solid fa-circle-user: 关于&留言: /about/ || fas fa-heart 备忘录: /talk/ || fa-solid fa-walkie-talkie 建站史: /history/ || fa-regular fa-clock 摸鱼: https://rv.zhsher.cn/Game_box/game/ || fa-solid fa-fish-fins 云盘: https://icloud.zhsher.cn || fa-solid fa-cloud 站点监控: https://status.zhsher.cn/status/friend || fa-fw fa fa-heartbeat 虫洞: https://www.foreverblog.cn/go.html ||fa-solid fa-paper-plane
额外页面,以建站史为例,使用命令hexo new page history ,编写source/history/index.md
title: history date: 2022-05-01 15:56:57 toc: true top_img: 'https://picsum.photos/1920/942'
默认子目录是展开的,如果你想要隐藏,在子目录里添加 hide
List||fas fa-list||hide: Music: /music/ || fas fa-music Movie: /movies/ || fas fa-video
导航栏设置 修改主题配置文件_config.butterfly.yml
nav: logo: display_title: true fixed: false
代码框样式 修改主题配置文件_config.butterfly.yml
highlight_theme: mac light highlight_copy: true highlight_lang: true highlight_shrink: false highlight_height_limit: 200 code_word_wrap: true
code_word_wrap: true时需要额外配置
highlight: enable: true line_number: false auto_detect: false tab_replace: prismjs: enable: false preprocess: true line_number: false tab_replace: ''
社交图标 修改主题配置文件_config.butterfly.yml,图标查找矢量图标 Icons | Font Awesome ,QQ移动端无法跳转,需要在官方 开通服务
格式:图标名:url || 描述性文字 || color
social: fab fa-github: https://github.com/GC-ZF || Github fa-solid fa-c: https://blog.csdn.net/qq_49488584 || CSDN fab fa-qq: http://wpa.qq.com/msgrd?v=3&uin=1310446718&site=qq&menu=yes || QQ fas fa-envelope-open-text: mailto:1310446718@qq.com || Email
主页文章节选(自动节选和文章页description) description在front-matter(即自动生成时MD时前面的内容)
description: 只显示description both: 优先选择description,如果没有配置description,则显示自动节选的内容 auto_excerpt:只显示自动节选 false: 不显示文章内容 修改主题配置文件_config.butterfly.yml
index_post_content: method: 2 length: 500
顶部图 如果不要显示顶部图,可直接配置 disable_top_img: true
图片存放位置博客根目录/source/Hexo_img,修改主题配置文件_config.butterfly.yml
主页封面图片
index_img: /Hexo_img/background.png
文章详情页顶部图片,当没有在front-matter设置top_img和cover的情况下会显示该图
default_top_img: /Hexo_img/default_top_img.jpeg
归档页顶部图片
archive_img: https://picsum.photos/1920/942
tag页顶部图
tag_img: https://picsum.photos/470/315
category页顶部图
category_img: https://picsum.photos/470/315
tag_per_img 和 category_per_img 是 3.2.0 新增的内容,可对 tag 和 category 进行单独的配置
并不推荐为每个 tag 和每个 category 都配置不同的顶部图,因为配置太多会拖慢生成速度
tag_per_img: aplayer: https://xxxxxx.png android: ddddddd.png category_per_img: 随想: hdhdh.png 推荐: ddjdjdjd.png
文章封面 文章的markdown文档上,在Front-matter添加cover,并填上要显示的图片地址
如果不配置cover,可以设置显示默认的cover
如果不想在首页显示cover,可以设置为false,修改主题配置文件_config.butterfly.yml
cover: index_enable: true aside_enable: true archives_enable: true position: both default_cover: - https://picsum.photos/id/1018/470/315 - https://picsum.photos/id/1044/470/315 - https://picsum.photos/id/1056/470/315
文章页相关配置 修改主题配置文件_config.butterfly.yml,这个选项是用来显示文章的相关信息的
post_meta: page: date_type: both date_format: data categories: true tags: false label: true post: date_type: both date_format: date categories: true tags: true label: true
文章版权 修改主题配置文件_config.butterfly.yml,博客文章底部展示文章版权和许可协议
post_copyright: enable: true decode: false license: CC BY-NC-SA 4.0 license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/
从3.0.0开始,支持对单独文章设置版权信息,可以在文章Front-matter单独设置
copyright_author: xxxx copyright_author_href: https://xxxxxx.com copyright_url: https://xxxxxx.com copyright_info: 此文章版权归xxxxx所有,如有转载,请註明来自原作者
文章打赏 修改主题配置文件_config.butterfly.yml,给文章结尾设置打赏按钮
reward: enable: true QR_code: - img: /Hexo_img/wechat.png link: text: 微信 - img: /Hexo_img/alipay.jpg link: text: 支付宝
TOC目录 修改主题配置文件_config.butterfly.yml,在文章页会有一个目录,用于显示TOC
toc: post: true page: false number: true expand: false style_simple: false scroll_percent: true
为特定文章配置 在文章md文件的头部,加入toc_number是否显示章节数和toc是否显示目录,并配置true或者false即可。
主题会优先判断文章Markdown的Front-matter是否有配置,如有,则以Front-matter的配置为准。否则,以主题配置文件中的配置为准
相关文章 修改主题配置文件_config.butterfly.yml,相关文章推荐的原理是根据文章tags的比重来推荐
related_post: enable: true limit: 6 date_type: created
文章锚点 开启文章锚点后,当你在文章页进行滚动时,浏览器链接会根据标题ID进行替换 (注意: 每替换一次,会留下一个历史记录。所以如果一篇文章有很多锚点的话,网页的历史记录会很多)
修改主题配置文件_config.butterfly.yml,默认false
anchor: button: enable: false always_show: false icon: auto_update: false
文章过期提醒 可设置是否显示文章过期提醒,以更新时间为基准
limit_day: 距离更新时间多少天才显示文章过期提醒 message_prev : 天数之前的文字 message_next:天数之后的文字 修改主题配置文件_config.butterfly.yml
noticeOutdate: enable: false style: flat limit_day: 365 position: top message_prev: It has been message_next: days since the last update, the content of the article may be outdated.
文章编辑按钮 修改主题配置文件_config.butterfly.yml,在文章标题旁边显示一个编辑按钮,点击会跳转到对应的链接去
post_edit: enable: false url:
文章分页按钮 修改主题配置文件_config.butterfly.yml,设置分页的逻辑false时不显示分页
头像 修改主题配置文件_config.butterfly.yml
avatar: img: https://q1.qlogo.cn/g?b=qq&nk=1310446718&s=5 effect: false
图片描述 可开启图片Figcaption描述文字显示,优先显示图片的 title 属性,然后是 alt 属性
修改主题配置文件_config.butterfly.yml,默认关闭
复制相关配置 可配置网站是否可以复制、复制的内容是否添加版权信息
enable:是否开启网站复制权限 copyright:复制的内容后面加上版权信息 enable:是否开启复制版权信息添加 limit_count:字数限制,当复制文字大于这个字数限制时,将在复制的内容后面加上版权信息 修改主题配置文件_config.butterfly.yml
copy: enable: true copyright: enable: true limit_count: 50
博客年份 since是一个来展示你站点起始时间的选项。它位于页面的最底部
修改主题配置文件_config.butterfly.yml
footer: owner: enable: true since: 2022 custom_text: <div>满地都是六便士 我想抬头看月亮</div><div><a onclick="window.open('url')" class="footer-a">备:没服务器...</a></div> copyright: true
页脚自定义脚本(备案信息) custom_text是一个给你用来在页脚自定义文本的选项。通常你可以在这里写声明文本等。支持 HTML。
修改主题配置文件_config.butterfly.yml
custom_text: Hi, welcome to my <a href="https://butterfly.js.org/">blog</a>!
对于部分人需要写 ICP 的,也可以写在 custom_text 里
custom_text: <a href="icp链接"><img class="icp-icon" src="icp图片"><span>备案号:xxxxxx</span></a>
右下角按钮 简繁转换 简体繁体互换,右下角会有简繁转换按钮
修改主题配置文件_config.butterfly.yml,默认关闭
translate: enable: true default: 简 defaultEncoding: 1 translateDelay: 0 msgToTraditionalChinese: "繁" msgToSimplifiedChinese: "简"
夜间模式 右下角会有夜间模式按钮
修改主题配置文件_config.butterfly.yml,默认开启
darkmode: enable: true button: true autoChangeMode: 2 start: end:
V2.0.0 开始增加一个选项,可开启自动切换light mode 和 dark mode
autoChangeMode: 1 跟随系统而变化,不支持的浏览器/系统将按照时间晚上6点到早上6点之间切换为 dark mode
autoChangeMode: 2 只按照时间 晚上6点到早上6点之间切换为 dark mode,其余时间为light mode
autoChangeMode: false 取消自动切换
阅读模式 阅读模式下会去掉除文章外的内容,避免干扰阅读。只会出现在文章页面,右下角会有阅读模式按钮
修改主题配置文件_config.butterfly.yml,默认开启
滚动状态百分比 修改主题配置文件_config.butterfly.yml,默认开启
rightside_scroll_percent: true
按钮排序 修改主题配置文件_config.butterfly.yml,默认即可
rightside_item_order: enable: false hide: show:
侧边栏设置 侧边排版 可自行决定哪个项目需要显示,可决定位置,也可以设置不显示侧边栏
left侧边栏靠左边right侧边栏靠右边hide隐藏所有display单独设置显示哪个修改主题配置文件_config.butterfly.yml
aside: enable: true hide: false button: true mobile: true position: right display: archive: true tag: true category: true card_author: enable: true description: button: enable: true icon: fab fa-github text: Follow Me link: https://github.com/GC-ZF card_announcement: enable: true content: 在没有经济独立的前提下,一切自由都是诱拐,一切个性都是欺骗 card_recent_post: enable: true limit: 5 sort: date sort_order: 4 card_categories: enable: true limit: 8 expand: none sort_order: 5 card_tags: enable: true limit: 40 color: false orderby: random order: 1 sort_order: 6 card_archives: enable: true type: monthly format: MMMM YYYY order: -1 limit: 8 sort_order: 7 card_webinfo: enable: true post_count: true last_push_date: true sort_order: 8
访问人数统计 修改主题配置文件_config.butterfly.yml,默认全开。使用不蒜子统计
busuanzi: site_uv: true site_pv: true page_pv: true
运行时间 网页已运行时间
修改主题配置文件_config.butterfly.yml,默认false
runtimeshow: enable: true publish_date: 5 /1/2022 00 :00:00
最新评论 最新评论只会在刷新时才会去读取,并不会实时变化
由于 API 有 访问次数限制,为了避免调用太多,主题默认存取期限为 10 分钟。也就是说,调用后资料会存在 localStorage 里,10分钟内刷新网站只会去 localStorage 读取资料。 10 分钟期限一过,刷新页面时才会去调取 API 读取新的数据。( 3.6.0 新增了 storage 配置,可自行配置缓存时间)
在侧边栏显示最新评论板块
修改主题配置文件_config.butterfly.yml,默认关闭
limit:显示数量 storage:设置缓存时间 avatar:是否显示头像 newest_comments: enable: true sort_order: 3 limit: 6 storage: 10 avatar: false
自定义添加栏目 自定义侧边栏 | Butterfly :在后续魔改中会用到,例如访客统计侧边栏
标签外挂 详见官方文档
以下来自Butterfly 安裝文檔(四) 主題配置-2 | Butterfly
评论 Valine一部分功能(表情库、邮件提醒等等)需要借助其它第三方。Valine配置Leancloud有个小坑,如果认证支付宝显示当前设备不支持刷脸,支付宝退出重登就好
改为livere(韩国)配置很快,大概五分钟就好,支持表情、图片,但是不能自定义评论框的样式,必须登录QQ等才能发表评论
2022.5.1 最后的倔强,还是喜欢免登录,更改评论为tiwkoo
小坑:MongoDB数据库配置时,连接字符串密码,mongodb+srv://xxxxxx:<password>@cluster0.i7omd.mongodb.net/myFirstDatabase?retryWrites=true&w=majority,替换密码时尖括号< >需要去掉
数据导出 2022.8.5 墙裂推荐twikoo。作者是95后小哥哥,人巨好,随时回复网友的各种疑难杂症Issues · imaegoo/twikoo 。另外,熟读中文文档后,官网已有详细的特色简介,着重点名几个深得我心的功能!
支持Valine、Disqus、Artalk、Twikoo数据迁移 评论人工审核 支持私有部署 支持自建的兰空图床 (本来是没有的,小哥专门加的) 可以修改评论信息(参考下文) 关于数据迁移,我之前是部署在MongoDB,但是如果有自己服务器的话,评论延迟会快一点,参考作者教程评论数据导出教程 - iMaeGoo’s Blog ,有一点点踩坑的地方,总结一下
根据作者说明,利用 MongoDB 数据库工具运行导出命令
mongoexport --uri 这里换成刚才复制的地址 --collection comment --type json --out twikoo-comments.json
可能出现的错误(耗费三小时与@二花 ,bing、谷歌、stack overflow、csdn,win、Mac、Ubuntu,轮番战斗!)
mongoexport --uri 这里换成刚才复制的地址 --collection comment --forceTableScan --type json --out twikoo-comments.json
微软解决办法
连接有三种方法,用最下面有一个GUI工具
没有工具可以先选择I do don have MongoDB Compass,或者官网找MongoDB Compass 安装。打开软件连接数据库,uri 默认1.12 or later ,如果出现queryTxt ETIMEOUT超时,参考官网Error: queryTxt ETIMEOUT - MongoDB Developer Community Forums ,换用1.11 or later
连接数据库后,可以通过工具对评论修改、数据导出导入,如果忘记密码删除config 中ADMIN_PASS:"xxxx",私有部署在文件夹db.json.1 内删除ADMIN_PASS:"xxxx",之后重新打开博客设置。Vercel部署+Mongo Compass辅助或私有部署,四舍五入,也有了类似Typecho后台评论管理了嘿嘿
数据备份 小tips:网站数据备份相当重要,宝塔可以直接对站点备份,但评论备份无法实现,服务器自带python环境,所以我做了一个python代码,利用crontab -e或宝塔面板中的计划任务定时备份,在目录下backuplog.txt会记录每一次备份日志
2022.09.27 新增无服务器备份方案:Twikoo评论定时备份方案 | 张时贰
Vercel部署,将代码存放在MongoDB 数据库工具同级路径下,按需修改30行(清理备份)、35行(MONGODB_URI)
""" @Author:张时贰 @Date:2022年08月08日 @CSDN:张时贰 @Blog:zhsher.cn """ import osfrom datetime import datetimeimport sysclass Logger ( object ): def __init__ (self, fileN="Default.log" ): self.terminal = sys.stdout self.log = open ( fileN, "a" ) def write (self, message ): self.terminal.write ( message ) self.log.write ( message ) def flush (self ): pass sys.stdout = Logger ( "backuplog.txt" ) print ( "--------------------------------------------------------------\n" )now_time = datetime.now () now_time_day = now_time.day data = f"{now_time.year} 年{now_time.month} 月{now_time.day} 日" delete_day = [ 15 , 30 ] if now_time_day in delete_day: os.system ( 'rm *.json -f' ) print ( data + " 清空备份文件" ) MONGODB_URI = 'mongodb+srv://xxx:xxx@xxxxxxx/myFirstDatabase' commond = 'mongoexport --uri ' + f'{MONGODB_URI} ' + ' --collection comment --forceTableScan --type json --out ' + f"{now_time.year} 年{now_time.month} 月{now_time.day} 日.json" code = os.system ( commond ) if code == 0 : print ( data + " 备份成功" ) else : print ( data + " 备份失败,请检查python文件中MONGODB_URI值是否正确" ) print ()
私有部署,代码存放位置任意,修改35行(原始路径)、36行(备份路径),都用绝对路径,但不要与私有部署在相同路径下,因为定时清理会清掉所有json文件
""" @Author:张时贰 @Date:2022年08月08日 @CSDN:张时贰 @Blog:zhsher.cn """ import osfrom datetime import datetimeimport sysclass Logger ( object ): def __init__ (self, fileN="Default.log" ): self.terminal = sys.stdout self.log = open ( fileN, "a" ) def write (self, message ): self.terminal.write ( message ) self.log.write ( message ) def flush (self ): pass sys.stdout = Logger ( "backuplog.txt" ) print ( "--------------------------------------------------------------\n" )now_time = datetime.now () now_time_day = now_time.day data = f"{now_time.year} 年{now_time.month} 月{now_time.day} 日" delete_day = [ 15 , 30 ] if now_time_day in delete_day: os.system ( 'rm *.json -f' ) print ( data + " 清空备份文件" ) init_path='/xxxxx/bin/db.json.1' backup_path='/xxxxx/bin/backup/' init_path='"' +init_path+'"' backup_path='"' +backup_path+f"/{now_time.year} 年{now_time.month} 月{now_time.day} 日.json" +'"' commond = 'cp ' +init_path+" " +backup_path code = os.system ( commond ) if code == 0 : print ( data + " 备份成功" ) else : print ( data + " 备份失败,请检查python文件中init_path和backup_path是否正确或备份路径是否有读写权限" ) print ()
在线聊天 感觉也用不到…,想弄看文档吧Butterfly 安裝文檔(四) 主題配置-2 | Butterfly
分享 官方提供三种格式,本博客使用的默认服务商sharejs
sharejs: enable: true sites: facebook,twitter,wechat,weibo,qq
本地搜索 安装依赖
npm install hexo-generator-search --save
修改主题配置文件_config.butterfly.yml,默认关闭,preload代表预加载
local_search: enable: true preload: true CDN:
广告 影响阅读体验,不加!
数学 主题自带足矣,第三方插件:Butterfly 安裝文檔(四) 主題配置-2 | Butterfly
美化 自定义主题色 可以修改大部分UI颜色,默认全注释不修改,我使用的默认
修改主题配置文件_config.butterfly.yml,颜色值必须被双引号包裹,就像”#000”而不是#000。否则将会在构建的时候报错!
theme_color: enable: true main: "#49B1F5" paginator: "#00c4b6" button_hover: "#FF7242" text_selection: "#00c4b6" link_color: "#99a9bf" meta_color: "#858585" hr_color: "#A4D8FA" code_foreground: "#F47466" code_background: "rgba(27, 31, 35, .05)" toc_color: "#00c4b6" blockquote_padding_color: "#49b1f5" blockquote_background_color: "#49b1f5" scrollbar_color: "#49b1f5"
网站背景 默认显示白色,可设置图片或者颜色,修改主题配置文件_config.butterfly.yml
background: url(/Hexo_img/config/background.png)
background:’#49B202’
修改主题配置文件_config.butterfly.yml
留空/false: 显示默认的颜色 img链接:图片的链接,显示所配置的图片 颜色(HEX值 - #0000FF,RGB值 - rgb(0,0,255),颜色单词 - orange,渐变色 - linear-gradient( 135deg, #E2B0FF 10%, #9F44D3 100%)) true:显示跟 top_img 一样 小tip,用rgba(255,255,255,0)使页脚透明
打字效果 修改主题配置文件_config.butterfly.yml
activate_power_mode: enable: true colorful: true shake: true mobile: false
背景特效 修改主题配置文件_config.butterfly.yml,三选一
canvas_ribbon: enable: false size: 150 alpha: 0.6 zIndex: -1 click_to_change: false mobile: false canvas_fluttering_ribbon: enable: false mobile: false canvas_nest: enable: true color: '0,0,255' opacity: 0.7 zIndex: -1 count: 99 mobile: false
鼠标点击效果 修改主题配置文件_config.butterfly.yml,三选一
fireworks: enable: false zIndex: 9999 mobile: false click_heart: enable: false mobile: false ClickShowText: enable: true text: - 鬼 - 才 - 小 - 张 - 同 - 学 fontSize: 15px random: false mobile: false
页面美化 会改变ol、ul、h1-h5的样式
field配置生效的区域
修改主题配置文件_config.butterfly.yml
beautify: enable: true field: site title-prefix-icon: '\f0c1' title-prefix-icon-color: "#F47466"
title-prefix-icon填写的是开始使用 – Font Awesome 中文网 的icon的Unicode数
未开启美化
开启美化
自定义字体和字体大小(未设置) 全局字体 可自行设置字体的font-family,如不需要配置,请留空
修改主题配置文件_config.butterfly.yml
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: consolas, Menlo, "PingFang SC" , "Microsoft JhengHei" , "Microsoft YaHei" , sans-serif
blog标题字体 可自行设置字体的font-family,如不需要配置,请留空。如不需要使用网络字体,只需要把font_link留空就行
修改主题配置文件_config.butterfly.yml
blog_title_font: font_link: https://fonts.googleapis.com/css?family=Titillium+Web&display=swap font-family: Titillium Web, 'PingFang SC' , 'Hiragino Sans GB' , 'Microsoft JhengHei' , 'Microsoft YaHei' , sans-serif
网站副标题 修改主题配置文件_config.butterfly.yml,可设置主页中显示的网站副标题或者喜欢的座右铭,将enable设置为true开启,默认关闭
subtitle: enable: true effect: true typed_option: source: false sub: - 劝君莫惜金缕衣,劝君惜取少年时 - 花开堪折直须折,莫待无花空折枝 - 出自金缕衣
修改副标题字体样式,位置\themes\butterfly\source\css\_layout\head.styl,43行
#site-subtitle color: var(--white) //此处修改为白色 font-size: 1.05em // 字体大小 +minWidth768() font-size: 1.40em // 字体大小
主页top_img大小 默认的显示为全屏。site-info的区域会居中显示
注意:index_top_img_height的值不能使用百分比,2个都不填的话,会使用默认值
修改主题配置文件_config.butterfly.yml
index_site_info_top: index_top_img_height:
页面加载动画preloader 当进入网页时,因为加载速度的问题,可能会导致top_img图片出现断层显示,或者网页加载不全而出现等待时间,开启preloader后,会显示加载动画,等页面加载完,加载动画会消失
自定义动画参考学长Hexo 添加加载动画 | 超逸の博客
修改主题配置文件_config.butterfly.yml
preloader: enable: false source: 1 pace_css_url:
PWA(未配置) 渐进式增强 Web 应用,访客在安装插件Lighthouse后可离线缓存博客内容,用处不大
字数统计 安装
npm install hexo-wordcount --save
修改主题配置文件_config.butterfly.yml
wordcount: enable: true post_wordcount: true min2read: true total_wordcount: true
图片大图查看 修改主题配置文件_config.butterfly.yml,二选一,默认第二个
medium_zoom: false fancybox: true
Snackbar弹窗 修改主题配置文件_config.butterfly.yml
snackbar: enable: true position: top-right bg_light: '#49b1f5' bg_dark: '#1f1f1f'
其它配置 CSS前缀 弊端大,跳过
Open Graph 在 head 里增加一些 meta 资料,例如缩略图、标题、时间等等。当你分享网页到一些平台时,平台会读取 Open Graph 的内容,展示缩略图,标题等等信息
修改主题配置文件_config.butterfly.yml
Open_Graph_meta: enable: true option:
Instantpage 鼠标悬停到链接上超过 65 毫秒时,Instantpage 会对该链接进行预加载,可以提升访问速度,默认关闭
修改主题配置文件_config.butterfly.yml
Pangu 自动在网页中所有的中文字和半形的英文、数字、符号之间插入空白。
修改主题配置文件_config.butterfly.yml
pangu: enable: true field: site
Pjax 当用户点击链接,通过ajax更新页面需要变化的部分,然后使用HTML5的pushState修改浏览器的URL地址,这样可以不用重复加载相同的资源(css/js), 从而提升网页的加载速度
修改主题配置文件_config.butterfly.yml
pjax: enable: true exclude: - /music/ - /no-pjax/
对于一些第三方插件,有些并不支持 pjax 。可以把网页加入到 exclude 里,这个网页会被 pjax 排除在外。点击该网页会重新加载网站,使用pjax后,一些自己DIY的js可能会无效
Inject自定义CSS JS 修改主题配置文件_config.butterfly.yml,后面会具体应用实践
inject: head: - <link rel="stylesheet" href="css/xxx.css"> bottom: - <script src="js/xxx.js"></script>
以下来自Butterfly 安裝文檔(六) 進階教程 | Butterfly ,自定义代码配色、自定义侧边栏未记录
音乐 文档:Butterfly添加全局吸底Aplayer教程 | Butterfly
插件:hexo-tag-aplayer | Github
在md文件内可以通过html的方式直接引入
<div class ="aplayer" data-id ="000PeZCQ1i4XVs" data-server ="tencent" data-type ="artist" data-mutex ="true" data-preload ="auto" data-theme ="#3F51B5" > </div >
也可以通过插件写进文章中,主题会自动渲染为html格式,见仁见智,选自己喜欢的就行
安装
npm install --save hexo-tag-aplayer
修改配置文件 _config.yml ,新增配置,之后在需要使用音乐的文章Front-matter 添加aplayer: true
aplayer: meting: true asset_inject: false
更多示例参考插件文档
<!-- 简单示例 (id, server, type) --> {% meting "60198" "netease" "playlist" % } <!-- 进阶示例 --> {% meting "60198" "netease" "playlist" "autoplay" "mutex:false" "listmaxheight:340px" "preload:none" "theme:#ad7a86" % }
电影 文档:butterfly-plugins/hexo-butterfly-douban | Github
说说 本博客目前使用Leancloud国内部署+Artitalk.js
无服务器首推Heo哥的静态,免部署好实现,之后KK Api可以动态发文。有服务器首推Memos。见仁见智选合适自己的就好
全局吸底播放器 Butterfly添加全局吸底Aplayer教程 | Butterfly
修改主题配置文件_config.butterfly.yml,开启aplayerInject
aplayerInject: enable: true per_page: true
插入 Aplayer html,例如网易云,找一个歌单点击分享,复制链接,把网址里的id换一下(其它平台data-server参考官方文档)
inject: head: bottom: - <div class="aplayer no -destroy" data-id="60198" data-server="netease" data-type="playlist" data-fixed="true" data-autoplay="false"> </div>
icon矢量图标 主题内置:矢量图标 Icons | Font Awesome ,例如社交信息中的Github,直接填写图标名称即可
fab fa-github: https://github.com/GC-ZF || Github
引入第三方iconfont-阿里巴巴矢量图标库 ,挑选图标加入自己账户中,修改主题配置文件_config.butterfly.yml
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="//at.alicdn.com/t/c/font_xxxx.css"> # 图标库的地址
调整样式,新建source/css/alico.css
.iconfont { font-size : 18px ; }
使用格式:iconfont 图标名称
iconfont icon-github: https://github.com/GC-ZF || Github
至此主题文档已全部介绍完成
其它配置 网站图标,修改主题配置文件_config.butterfly.yml
favicon: /img/favicon.png
图片懒加载,图片没加载出来的时候,出现一个动图转转转的文章页样式,修改主题配置文件_config.butterfly.yml
lazyload: enable: true field: site placeholder: /Hexo_img/loading.gif blur: true
六、优化 博客备份(版本控制) 及时对博客备份是一个好习惯!不会的同学根据卷二兔的视频 跟着走。通过git版本控制还可以做历史回滚操作,git功能十分强大,B站看一些视频就可以掌握啦!
在Github新建一个私有仓库 ,例如地址为https://github.com/GC-ZF/Blog-Backups.git
在博客根路径下执行,之后出现.git文件
新建.gitignore文件,创建忽略规则(这些文件是可以二次下载的所以忽略上传)
.DS_Store Thumbs.db db.json *.log node_modules/ public/ .deploy*/ .vscode/ /.idea/ .deploy_git*/ .idea themes/butterfly/.git themes/webstack/.git
上传仓库
git add . git commit -m "我的第一次提交" git remote add origin 仓库地址url git push --set-upstream origin main
当博客更改后需要备份时
git add . git commit -m "我的备份" git push
当需要重新获取博客文件时,npm install会检查package.json里记录了那些依赖,所以就不用一个一个安了
git clone 仓库地址 git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly npm install hexo g hexo s
自动化部署 此节较长,参考:Hexo博客利用Github Action自动化部署 | 张时贰
前面做了版本控制,一个仓库用来存放源文件,一个仓库github.io用来存放静态文件,而每次都需要繁琐的八条命令!
hexo clean hexo g hexo algolia gulp hexo d git add . git commit -m "提交博客" git push
渲染静态文件还需要等候,有没有什么办法可以仅通过三条git命令达到部署需求?Github Action!通过push私有仓库触发Action自动构建静态文件并推送给github.io仓库、服务器、vercel等平台
简化命令 每次输入hexo clean && hexo g && hexo s十分费事,可以简化命令
原文地址:通过alias自定义终端命令实现Hexo博客的高效使用,简化你的终端命令 | 张洪Heo
Mac设备可以参考Heo哥,我这里提供win下方案
修改[BlogRoot]/package.json,追加一行自定义命令
"scripts": { "build": "hexo generate", "clean": "hexo clean", "deploy": "hexo deploy", "server": "hexo server", + "localhost": "hexo clean & hexo g & hexo s" }
终端输入npm run localhost,测试跑通即可。左图为webstorm双击运行,右图为vscode选择npm运行
如果两个软件都没安装且现有编译器没有运行功能,新建[BlogRoot]/run.bat,双击运行
hexo clean && hexo g && hexo s
gulp压缩 原文地址:使用gulp压缩博客静态资源 | Akilarの糖果屋
Hexo博客本身由静态文件组成,通过gulp,可以压缩html、css、js文件从而达到快速加载的效果
安装gulp插件
npm install --global gulp-cli npm install gulp --save
安装压缩html插件
npm install gulp-htmlclean --save-dev npm install gulp-html-minifier-terser --save-dev
安装压缩CSS插件
npm install gulp-clean-css --save-dev
安装压缩js插件
npm install gulp-terser --save-dev
安装压缩字体插件(仅支持压缩ttf格式的字体包)
npm install gulp-fontmin --save-dev
为Gulp创建gulpfile.js任务脚本。新建[Blogroot]/gulpfile.js
var gulp = require ('gulp' );var cleanCSS = require ('gulp-clean-css' );var htmlmin = require ('gulp-html-minifier-terser' );var htmlclean = require ('gulp-htmlclean' );var fontmin = require ('gulp-fontmin' );var terser = require ('gulp-terser' );gulp.task ('compress' , async () =>{ gulp.src (['./public/**/*.js' , '!./public/**/*.min.js' ]) .pipe (terser ()) .pipe (gulp.dest ('./public' )) }); gulp.task ('minify-css' , () => { return gulp.src (['./public/**/*.css' ]) .pipe (cleanCSS ({ compatibility : 'ie11' })) .pipe (gulp.dest ('./public' )); }); gulp.task ('minify-html' , () => { return gulp.src ('./public/**/*.html' ) .pipe (htmlclean ()) .pipe (htmlmin ({ removeComments : true , collapseWhitespace : true , collapseBooleanAttributes : true , removeEmptyAttributes : true , removeScriptTypeAttributes : true , removeStyleLinkTypeAttributes : true , minifyJS : true , minifyCSS : true , minifyURLs : true })) .pipe (gulp.dest ('./public' )) }); function minifyFont (text, cb ) { gulp .src ('./public/fonts/*.ttf' ) .pipe (fontmin ({ text : text })) .pipe (gulp.dest ('./public/fontsdest/' )) .on ('end' , cb); } gulp.task ('mini-font' , (cb ) => { var buffers = []; gulp .src (['./public/**/*.html' ]) .on ('data' , function (file ) { buffers.push (file.contents ); }) .on ('end' , function ( ) { var text = Buffer .concat (buffers).toString ('utf-8' ); minifyFont (text, cb); }); }); gulp.task ('default' , gulp.parallel ( 'compress' , 'minify-css' , 'minify-html' ,'mini-font' ))
在每次运行完hexo generate生成静态页面后,运行gulp对其进行压缩
hexo clean hexo generate gulp hexo deploy
图片压缩 图片压缩一方面可以加快加载速度,一方面减少出站流量(买的CDN也是钱哇!)。小张只对后台监控流量高的图片进行了压缩,大概逻辑就是能替换就替换,替换不了就压缩
meowtec/Imagine :现在在用的软件,支持win、mac,批量转格式压缩一体,UI简洁,最重要的是压缩后不仅体积小且画质清晰
格式工厂 :转格式压缩一体,但多了很多图片以外的功能,所以UI复杂一些不太喜欢
TinyPNG :在线压缩网站,质量高但一次最多20张
Caesium :批量压缩软件,无限制,人物图有些失真
Imgbot :Github插件,提交自动压缩发起pr
搜索 原文地址:
前文使用了本地搜索插件,Algolia是一款更快速的搜索工具,每月只有 10000 次调用额度。两种搜索一秒内出结果但本地搜索需要预先加载文件当刚进网站就点搜索时,Algolia更快
卸载本地搜索插件
npm uninstall hexo-generator-search
修改主题配置文件_config.butterfly.yml,关闭本地搜索
local_search: enable: false preload: true CDN:
注册 Algolia 并创建一个应用
安装
npm install hexo-algoliasearch --save
修改配置文件 _config.yml,在最下面添加appId、apiKey、adminApiKey、indexName 根据自己的情况填写
plugins: - hexo-algoliasearch algolia: appId: "RNPIZK8E" apiKey: "8ee7fe3d8cad0c9a545a96e8bc26" adminApiKey: "117700ad23daaa7f4ffe19a48da8" chunkSize: 5000 indexName: "Hexo_Blog" fields: - content:strip:truncate,0,200 - tags - permalink - excerpt:strip - title - categories
修改主题配置文件_config.butterfly.yml
algolia_search: enable: true hits: per_page: 6
修改/themes/butterfly/source/js/search/algolia.js,设置按回车搜索以及提示词
const searchBox = instantsearch.widgets .searchBox ({ container : '#algolia-search-input' , showReset : false , showSubmit : true , searchAsYouType : false , placeholder : "输入关键词后,按下回车键即可搜索文章..." , showLoadingIndicator : true })
提交搜索hexo clean & hexo g & hexo algolia & hexo d
博客升级 升级前做好备份!!!
对npm升级
npm -v npm install npm@latest -g npm cache clean -f
对hexo及插件升级,在[BlogRoot]下操作
npm install -g npm-check-updates ncu -u npm install ncu npm install 单个包名 npm install -g npm-upgrade npm update hexo -v
对Butterfly升级,在[BlogRoot]/theme/butterfly下操作
根据Butterfly 更新日志 ,对[BlogRoot]/_config.butterfly.yml增删新版的配置
隐藏文章 原文地址:如何优雅隐藏 Hexo 文章 | CC的部落格
写好但不发布,方法蛮多的,Front-Matter我认为更方便一些
在文章Front-Matter部分配置published参数
跳过渲染 原文地址:跳过渲染参考 MuJin’s Blog
有时我们需要放一些自己写好的html文件,但会被hexo渲染到主题中,这就需要跳过渲染
方法一:在文件前加Front matter,设置layout属性
方法二:修改配置文件 _config.yml
RSS不知道是什么,其实就是博客站点中一个小WIFI的按钮,打个比方,bili和知乎都支持RSS订阅,可以将RSS添加到订阅软件中,然后在软件中浏览指定的博主,不被大数据所轰炸,博客同理,在软件中浏览其他人的博客,这样就不需要来回去点网站访问了。
文档:hexo-generator-feed
安装插件
npm install hexo-generator-feed
修改配置文件 _config.yml,在最下面添加
feed: type: rss2 path: feed.xml limit: 10
hexo三连后,生成public/feed.xml,通过http://localhost:4000/feed.xml(域名/feed.xml)访问
关于RSS软件,近年下架了不少,推荐安卓 Focus ,Apple Store reader
域名解析 域名厂商很多,就不详细写绑定流程了,参考以下三篇文章,想要用二级域名参考第三篇,注意上传一个写有域名地址且文件命名CNAME的文件到Github仓库内,域名才会生效
Hexo个人免费博客(五) 使用自己的域名_
hexo 绑定自己的域名_
如何添加二级域名 Hydrion-Qlz的博客
SEO收录及优化 SEO收录简单来说就是可以让别人通过搜索一些关键字,然后搜到我们的博客内容
原文地址:
以下是我自己总结的,其实直接看B站教学就行,图文并茂没视频效果好
小tips:如果绑定了域名,不要使用xxx.github.io这个地址,绑定站点配置时会失败(301错误),如果使用的免费域名例如github.io百度基本不会收录
安装站点地图 站点地图即 sitemap, 是一个页面 ,通过插件会帮助我们将站内所有的网址记录在这个页面内,告诉搜索引擎网站上有哪些可供抓取的网页,以便搜索引擎可以更加智能地抓取网站
安装百度和 Google 的站点地图生成插件
npm install hexo-generator-baidu-sitemap --save npm install hexo-generator-sitemap --save
修改配置文件 _config.yml,在下面添加
sitemap: path: sitemap.xml baidusitemap: path: baidusitemap.xml
修改配置文件 _config.yml,添加域名地址
hexo clean & hexo g生成public/sitemap.xml,public/baidusitemap.xml。通过https://你的域名/sitemap.xml,https://你的域名/baidusitemap.xml检查,如果出现代码就说明插件安装成功
robots.txt 是一种存放于网站根目录下的 ASCII 编码的文本文件,它的作用是告诉搜索引擎此网站中哪些内容是可以被爬取的,哪些是禁止爬取的。robots.txt 放在博客目录下的 source 文件夹中,博客生成后在站点目录 /public/ 下,使用规则 ,我博客没啥东西,小蜘蛛爬就爬去吧,所以我没设置这项,感兴趣可以设置一下
User-agent: * Allow: / Disallow: Sitemap: https://域名/sitemap.xml Sitemap: https://域名/baidusitemap.xml
百度收录 百度站点
选择标签验证更方便一点点,修改主题配置文件_config.butterfly.yml,推送到服务器然后再点击验证
site_verification: - name: baidu-site-verification content: xxxxxxx
主动推送(已弃用) 主动推送最快最方便,通过插件每次会自动提交,但是百度虽然有插件但是收录效果没谷歌bing快…
安装
npm install hexo-baidu-url-submit --save
修改配置文件 _config.yml,在最下面添加
baidu_url_submit: count: 10 host: https://zhsher.cn token: path: baidu_urls.txt
修改配置文件 _config.yml,新增一个type
deploy: - type: git repository: xxxxx branch: main - type: baidu_url_submitter
之后每次hexo g会把最新的链接放在public/baidu_urls.txt,hexo d会自动读取文件内容并提交给百度,返回一段值remain当日剩余可提交,success成功提交,如果有error说明前面配的有问题
sitemap API提交旁边的sitemap即手动推送站点地图,其实主动推送插件就够用了(再旁边的手动提交就是一条一条的提交,sitemap更方便一些)
https://你的域名/sitemap.xml https://你的域名/baidusitemap.xml
谷歌收录 Google Search Console
两种验证方式,第二个方便一些
修改主题配置文件_config.butterfly.yml ,hexo c & g & d之后点击验证,之后等待收录就可以了
site_verification: - name: baidu-site-verification content: xxxxxxx +- name: google-site-verification + content: xxxxxxx
虽然没有百度的主动推送方式但同样也有sitemap,提交这个https://你的域名/sitemap.xml,bing同理
Bing收录 Bing
做完谷歌收录,bing这里直接导入谷歌即可
URL持久化 原文地址:
hexo 默认生成的文章地址路径是 网站名称/年/月/日/文章名称,这种链接对搜索爬虫是很不友好的,第一它的 url 结构超过了三层,太深了,abbrlink会优化为一段数字
安装
npm install hexo-abbrlink --save
修改配置文件 _config.yml,二选一,重新hexo c & g & d就看到效果了
permalink: posts/:abbrlink/
permalink: archives/:abbrlink.html abbrlink: alg: crc32 rep: hex
添加nofollow标签 原文地址:Hexo 框架 (六):SEO 优化及站点被搜索引擎收录设置
给非友情链接的出站链接添加「nofollow」 标签,nofollow 标签是由谷歌领头创新的一个「反垃圾链接」的标签,并被百度、yahoo 等各大搜索引擎广泛支持,引用 nofollow 标签的目的是:用于指示搜索引擎不要追踪(即抓取)网页上的带有 nofollow 属性的任何出站链接,以减少垃圾链接的分散网站权重
npm install hexo-filter-nofollow --save
修改配置文件 _config.yml,将 nofollow 设置为 true:
nofollow: enable: true field: site exclude: ''
三家主动推送 2023.01.06更新:因为谷歌、Bing一两天就会收录,而百度短则一周长则三四个月(一般是长)所以前面对百度加装了主动推送插件,如果你熟悉对Github的使用(不会也问题不大,作者乐特教程很详细),推荐Hexo-SEO-AutoPush: 每天自动提交url到百度和谷歌必应 插件,使用Github Action每日定时推送,省去手动hexo d才推送的操作
安装
npm install hexo-seo-autopush --save
修改配置文件 _config.yml,在最下面添加
hexo_seo_autopush: cron: 0 4 * * * baidu: enable: true date: created count: 10 bing: enable: true date: created count: 10 google: enable: true date: created count: 10
生成的 actions 是在github.io仓库下的.github/workflows/HexoSeoAutoPush.yml,点开头的文件或文件夹都会被视为隐藏文件,所以 hexo 不会将隐藏文件部署到 pages,需要新增配置ignore_hidden属性
deploy: type: git repo: https://github.com/<username>/<project> # example, https://github.com/hexojs/hexojs.github.io branch: gh-pages + ignore_hidden: false # 忽略隐藏文件及文件夹(目录)
hexo clean & hexo g后在[BlogRoot]/public生成baidu.txt、google.txt、bing.json则插件安装成功
之后在github.io仓库加入变量,为仓库做定时提交任务,具体参考文档
CDN加速 注:CDN需要中国大陆实名备案,且年费用在10元左右,如果你是无服务器部署,是不可以做备案的,可以尝试其它托管服务
Vercel 或Netlify :首推Vercel。俩平台用自己的Github注册导入github.io仓库即可,十分方便Gitee Page服务:国内Gitee的静态服务,但每次都需要点击手动检查部署,如果触发违禁词还需要重新编写文章,十分繁琐 2022.08.08,博客已稳定运行三个多月,感觉CDN加速没什么用,但始终逃不过真香定律。下图为加速后和加速前的ping测试
为什么使用 CDN 内容分发网络?
当用户直接访问源站中的静态内容时,可能面临的体验问题
客户离服务器越远,访问速度越慢。
客户数量越多,网络带宽费用越高。
跨境用户访问体验较差。
摘自店长的解释:
CDN(Content Delivery Network,内容分发网络)的作用很简单,顾名思义,把你的网站内容存在由各个节点构成的网络内,然后按照请求距离远近,让最近的节点去分发服务。
打个比方,把源站比作商品,CDN比作物流。 原本你从国内向海外发起海外购(访问源站),然后美国仓库发货(githubpage响应请求),可能要一周多才能到货。 现在套了全站CDN,你向美国发货,然后国内仓库(国内CDN缓存节点)比较了下,发现它在上海、北京、深圳等等地方都有一模一样的货(缓存内容),所以他看你在浙江,于是直接从离你最近的上海仓库发货(最近节点分发内容),于是,你上午下单,下午就到了。这样子,网站速度就快了。
CDN 如何改善您的网络体验
CDN 缓存内容后,用户仅需要访问就近的 CDN 节点即可获取静态内容。 缓解源站带宽压力,网络费用更低。 分布全球的跨境节点提升跨境访问体验。 简单点说,就是用一个服务商去帮你代理你的网站,从而做到全国加速访问的效果。其中有又拍云、百度云、腾讯云
文档经常更新,所以具体参考各个平台最新文档内容:内容分发网络 CDN 业务场景-场景教学-文档中心-腾讯云 、CDN配置方式(以腾讯云为例) - 忆梦小站
避坑:不建议开启IP访问限频配置 ,因为hexo静态文件居多,加载网页同时[BlogRoot]/source/js、[BlogRoot]/source/css等文件这些都算同一时间内的访问次数的,如果访问频率过低会导致页面加载错误,可以根据控制台报错找一个合适的频率配置
建议开启HTTPS配置(导入ssl证书)、HTTPS服务+强制跳转HTTPS、用量封顶配置 ,关掉IP限制但为了盗刷流量可以配置用量封顶
检查是否CDN加速是否起作用
站长工具 测试全国访问速度查看请求头 :网络控制台请求表头中包含x-cache-lookup:Cache Hit (代表成功从cdn上取得资源)命令行ping 域名:返回源地址而不是自己的服务器ip 站内资源CDN 原文地址:Butterfly CDN链接更改指南,替换jsdelivr提升访问速度 | 张洪Heo
既然不能为自己public文件夹下静态文件加速,那么主题渲染过程中也引入了很多外部资源,默认用的是国外厂商jsdelivr例如:https://cdn.jsdelivr.net/npm/xxx/dist/xxx.min.js,修改这些文件的地址也可以减少网站加载时间
所有外部资源文件的名称在
[BlogRoot]/themes/butterfly/scripts/events/cdn.js``[BlogRoot]/themes/butterfly/plugins.yml` 修改应遵循优先使用字节跳动的cdn。如果字节跳动静态资源公共库 没有则使用elemecdn,可以达到加速的效果。如果都没有可以和洪哥一样自己打包npm引用(我偷懒直接白嫖了嘻嘻)
修改主题配置文件_config.butterfly.yml
CDN: ...... option: + 在这里按需添加对应链接
jquery
https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.min.js
pjax
pjax: https://npm.elemecdn.com/pjax@latest/pjax.min.js
sharejs
sharejs: https://npm.elemecdn.com/butterfly-extsrc@latest/sharejs/dist/js/social-share.min.js sharejs_css: https://npm.elemecdn.com/butterfly-extsrc@latest/sharejs/dist/css/share.min.css
gitalk
gitalk: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/gitalk/1.7.2/gitalk.min.js gitalk_css: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/gitalk/1.7.2/gitalk.min.css
valine
https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/valine/1.4.16/Valine.min.js
disqusjs
disqusjs: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/disqusjs/1.3.0/disqus.js disqusjs_css: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/disqusjs/1.3.0/disqusjs.css
twikoo(这个是定制版)
twikoo: https://jsd.onmicrosoft.cn/npm/js-heo@1.0.3/twikoo/twikoo.all.min.js
twikoo(官方版)
twikoo: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twikoo/1.4.18/twikoo.all.min.js
waline
https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/waline/1.5.4/Waline.min.js
algolia
algolia_js: https://jsd.onmicrosoft.cn/npm/js-heo@1.0.11/algolia/algolia.js algolia_search_v4: https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/algoliasearch/4.12.1/algoliasearch-lite.umd.min.js
lazyload
lazyload: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vanilla-lazyload/17.3.1/lazyload.iife.min.js
instantpage
instantpage: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/instant.page/5.1.0/instantpage.min.js
typed
typed: https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/typed.js/2.0.12/typed.min.js
fancybox
fancybox_css_v4: https://jsd.onmicrosoft.cn/npm/@fancyapps/ui@4.0.31/dist/fancybox.css fancybox_v4: https://jsd.onmicrosoft.cn/npm/@fancyapps/ui@latest/dist/fancybox.umd.js
medium_zoom
https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/medium-zoom/1.0.6/medium-zoom.min.js
snackbar
snackbar_css: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/node-snackbar/0.1.16/snackbar.min.css snackbar: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/node-snackbar/0.1.16/snackbar.min.js
fontawesome
fontawesomeV6: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/font-awesome/6.0.0/css/all.min.css
translate
translate: https://jsd.onmicrosoft.cn/npm/hexo-theme-butterfly/source/js/tw_cn.js
aplayer
aplayer_css: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.css aplayer_js: https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.js meting_js: https://jsd.onmicrosoft.cn/npm/js-heo@1.0.12/metingjs/Meting.min.js
Prism
prismjs_js: https://jsd.onmicrosoft.cn/npm/prismjs@1.1.0/prism.js prismjs_lineNumber_js: https://jsd.onmicrosoft.cn/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js prismjs_autoloader: https://jsd.onmicrosoft.cn/npm/prismjs/plugins/autoloader/prism-autoloader.min.js
justifiedGallery
flickr_justified_gallery_js: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/justifiedGallery/3.8.1/js/jquery.justifiedGallery.min.js flickr_justified_gallery_css: https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/justifiedGallery/3.8.1/css/justifiedGallery.min.css
网站监控 可以监控多个站点或友链访问是否正常,发送错误时以邮件或短信方式通知
小张采用uptime-kuma
首先确认已安装docker环境:安装 Docker教程
安装uptime-kuma,并在网络控制台放行3001端口,通过服务器ip:3001访问
docker run -d --restart=always -p 3001:3001 -v /www/wwwroot/status/uptime-kuma/data:/app/data --name uptime-kuma louislam/uptime-kuma:1
选做:配置域名参考文档 uptime-kuma Wiki ,以nginx为例,/www/server/panel/vhost/nginx下创建status.conf文件,第三行为域名,四五行为证书路径
server { listen 443 ssl http2; server_name status.zhsher.cn; ssl_certificate /path/to/ssl/cert/crt; ssl_certificate_key /path/to/ssl/key/key; location / { proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; proxy_pass http://localhost:3001/; proxy_http_version 1 .1 ; proxy_set_header Upgrade $http_upgrade ; proxy_set_header Connection "upgrade" ; } }
但如果想和博客一样在宝塔面板的网站中显示(强迫症,列一起好知道自己有那些站点),可以添加一个空站点,之后修改配置文件或者做一个反代,二者效果相同
更新参考:uptime-kuma Wiki
docker pull louislam/uptime-kuma:1 docker stop uptime-kuma docker rm uptime-kuma docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1
新增状态页面后,在仪表盘可将网站入口设置为状态页面,之后仪表盘需要通过域名/dashboard进入
我的自定义css
body { } .info ,h1 ,.shadow-box ,.mb-4 ,.group-title ,.mt-5 {font-family : "华文新魏" ,"楷体" ;}
Hexo异步加载方案 原文地址:Hexo异步加载方案 | Akilarの糖果屋
Pjax适配 原文地址:我是这么适配pjax的 | Leonus
七、魔改 个人喜欢简约风格,魔改美化应遵循阅读体验、实用功能优先的原则,因而不做繁冗的增添与过于商业性质的修改
魔改由简到难,分为css、js文件引入修改,插件魔改,主题源码魔改。其中css分文件编写只是为了区分功能,实际操作可以合并为一个文件减少网页请求次数提高加载速度,Hexo异步加载方案 中有详细说明
在正式魔改前,先回顾一下主题文档是如何修改样式的
原文地址:使用Hexo搭建个人博客手摸手教学(16)|插入代码自定义样式及备案信息实现
卷二兔up主的其它css文件:constown/HexoStaticFile: HexoStaticFile
在博客界面右击想要修改的地方,点击检查,以底部为例,查到#footer-wrap,新建[BlogRoot]/source/css/style.css
#footer { background : transparent; } #footer-wrap { color : #0d0d0d ; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: - <link rel="stylesheet" href="/css/style.css">
修改主题配置文件_config.butterfly.yml,添加备案信息并修改#footer-a属性
footer: owner: enable: true since: 2022 custom_text: <div>满地都是六便士 我想抬头看月亮</div><div><a onclick="window.open('url')" class="footer-a">备没服务器...</a></div> copyright: true
同样在style.css中修改样式
#footer-a { color : #0d0d0d ; }
twikoo美化 twikoo输入提醒 原文地址:给你的评论添加一个输入提醒吧 | Leonus
新建[BlogRoot]/source/css/twikoo.css
.el-input .el-input--small .el-input-group .el-input-group--prepend :nth-child (1 ):before { content : '输入QQ号会自动获取昵称和头像🐧' ; } .el-input .el-input--small .el-input-group .el-input-group--prepend :nth-child (2 ):before { content : '收到回复将会发送到您的邮箱📧' ; } .el-input .el-input--small .el-input-group .el-input-group--prepend :nth-child (3 ):before { content : '可以通过昵称访问您的网站🔗' ; } .el-input .el-input--small .el-input-group .el-input-group--prepend :focus -within::before ,.el-input .el-input--small .el-input-group .el-input-group--prepend :focus -within::after { display : block; } .el-input .el-input--small .el-input-group .el-input-group--prepend ::before { display : none; position : absolute; top : -60px ; white-space : nowrap; border-radius : 10px ; left : 50% ; transform : translate (-50% ); padding : 14px 18px ; background : #444 ; color : #fff ; } .el-input .el-input--small .el-input-group .el-input-group--prepend ::after { display : none; content : '' ; position : absolute; border : 12px solid transparent; border-top-color : #444 ; left : 50% ; transform : translate (-50% , -48px ); }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/twikoo.css">
twikoo评论美化 原文地址:
新建[BlogRoot]/source/css/twikoo.css
方案一:注释很清晰可以自己微调,我修改了一下回复气泡的位置:.tk-content中新增 margin-left: 30px;
.tk-input [data-v-619b4c52] .el-textarea__inner { height : 130px !important ; } .tk-input [data-v-619b4c52] .el-textarea__inner :focus { background-image : none !important ; } .tk-replies { left : -70px ; width : calc (100% + 70px ); } .tk-replies .tk-avatar { width : 2.5rem !important ; height : 2.5rem !important ; } .tk-replies .tk-avatar img { width : 2.5rem !important ; height : 2.5rem !important ; } .tk-comments-container .tk-submit { position : relative; left : -70px ; } .tk-content { background : #00a6ff ; padding : 10px ; color : #fff ; border-radius : 10px ; font-size : 16px !important ; width : fit-content; max-width : 100% ; position : relative !important ; overflow : visible !important ; max-height : none !important ; margin-left : 30px ; } .tk-content img { max-width : 100% !important ; } .tk-content pre { white-space : pre-wrap; word-wrap : break-word; } .tk-content a { color : #eeecaa ; } .tk-content ::before { content : '' ; width : 0 ; height : 0 ; position : absolute; top : 20px ; left : -13px ; border-top : 2px solid transparent; border-bottom : 20px solid transparent; border-right : 15px solid #00a6ff ; border-left : 0px solid transparent; } .tk-master .tk-content { background : #ff8080 ; color : #fff ; width : fit-content; max-width : 100% ; } .tk-master .tk-content a { color : #eeecaa ; } .tk-master .tk-content ::before { content : '' ; width : 0 ; height : 0 ; position : absolute; top : 20px ; left : -13px ; border-top : 2px solid transparent; border-bottom : 20px solid transparent; border-right : 15px solid #ff8080 ; border-left : 0px solid transparent; } .tk-row [data-v-d82ce9a0] { max-width : 100% ; width : fit-content; } .tk-avatar { border-radius : 50% ; margin-top : 10px ; } [data-theme="dark" ] .tk-content { background : #000 ; color : #fff ; } [data-theme="dark" ] .tk-content a { color : #dfa036 ; } [data-theme="dark" ] .tk-content ::before { border-right : 15px solid #000 ; } [data-theme="dark" ] .tk-master .tk-content { background : #000 ; color : #fff ; } [data-theme="dark" ] .tk-master .tk-content a { color : #dfa036 ; } [data-theme="dark" ] .tk-master .tk-content ::before { border-top : 2px solid transparent; border-bottom : 20px solid transparent; border-right : 15px solid #000 ; border-left : 0px solid transparent; } @media screen and (min-width : 1024px ) { .tk-content { max-width : 75% ; width : fit-content; } .tk-master .tk-content { width : 75% ; } .tk-master .tk-content ::before { left : 100% ; border-left : 15px solid #ff8080 ; border-right : 0px solid transparent; } .tk-master .tk-avatar { position : relative; left : calc (75% + 70px ); } .tk-master .tk-row [data-v-d82ce9a0] { position : relative; top : 0px ; left : calc (75% - 230px ); } [data-theme="dark" ] .tk-master .tk-content ::before { border-left : 15px solid #000 ; border-right : 0px solid transparent; } } .tk-extras { opacity : 0 ; -ms-filter : "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)" ; filter : alpha (opacity=0 ); } .tk-content :hover + .tk-extras { -webkit-animation : tk-extras-fadeIn 0.5s linear; -moz-animation : tk-extras-fadeIn 0.5s linear; -o-animation : tk-extras-fadeIn 0.5s linear; -ms-animation : tk-extras-fadeIn 0.5s linear; animation : tk-extras-fadeIn 0.5s linear; -webkit-animation-fill-mode : forwards; -moz-animation-fill-mode : forwards; -o-animation-fill-mode : forwards; -ms-animation-fill-mode : forwards; animation-fill-mode : forwards; } @-moz-keyframes tk-extras-fadeIn { from { opacity : 0 ; -ms-filter : "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)" ; filter : alpha (opacity=0 ); } to { opacity : 1 ; -ms-filter : none; filter : none; } } @-webkit-keyframes tk-extras-fadeIn { from { opacity : 0 ; -ms-filter : "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)" ; filter : alpha (opacity=0 ); } to { opacity : 1 ; -ms-filter : none; filter : none; } } @-o-keyframes tk-extras-fadeIn { from { opacity : 0 ; -ms-filter : "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)" ; filter : alpha (opacity=0 ); } to { opacity : 1 ; -ms-filter : none; filter : none; } } @keyframes tk-extras-fadeIn { from { opacity : 0 ; -ms-filter : "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)" ; filter : alpha (opacity=0 ); } to { opacity : 1 ; -ms-filter : none; filter : none; } } .tk-input textarea { background-image : url ('https://zhsher.cn/Hexo_img/config/Twikooback.gif' ); min-height : 120px !important ; background-size :10em 10em ; transition : all 0.25s ease-in-out 0s ; } .tk-input textarea :focus { background-position -y: 130px ; transition : all 0.25s ease-in-out 0s }
方案二
:root { --zhangshier-radius : 7px ; --zhangshier-card-border-width : 1px ; } [data-theme=light] { --zhangshier-border-color : #e3e8f7 ; --zhangshier-card-bg : #fff ; --zhangshier-card-border : #e3e8f7 ; --style-border-always : 1px solid var (--zhangshier-card-border); --zhangshier-blue : #425AEF ; } [data-theme=dark] { --zhangshier-border-color : #42444a ; --zhangshier-card-bg : #1d1b26 ; --zhangshier-card-border : #42444a ; --style-border-always : 1px solid var (--zhangshier-card-border); --zhangshier-blue : #0084FF ; } .twikoo .tk-comments-container >.tk-comment { padding : 1rem ; border-radius : var (--zhangshier-radius); background : var (--zhangshier-card-bg); transition : .3s ; } [data-theme=light] .twikoo .tk-comments-container >.tk-comment { box-shadow : var (--card-box-shadow); } [data-theme=light] .twikoo .tk-comments-container >.tk-comment :hover { box-shadow : var (--card-hover-box-shadow); } [data-theme=dark] .twikoo .tk-comments-container >.tk-comment { border-style : solid; border-width : var (--zhangshier-card-border-width); border-color : var (--zhangshier-card-border); } .twikoo .tk-extra { border-radius : var (--zhangshier-radius); background : var (--zhangshier-card-bg); padding : 0.4rem ; margin-bottom : 1rem ; transition : .3s ; } [data-theme=light] .twikoo .tk-extra { box-shadow : var (--card-box-shadow); } [data-theme=light] .twikoo .tk-extra :hover { box-shadow : var (--card-hover-box-shadow); } [data-theme=dark] .twikoo .tk-extra { border-style : solid; border-width : var (--zhangshier-card-border-width); border-color : var (--zhangshier-card-border); } .twikoo .tk-expand { border-radius : var (--zhangshier-radius); } [data-theme=light] .twikoo .tk-expand { box-shadow : var (--card-box-shadow); } [data-theme=light] .twikoo .tk-expand :hover { box-shadow : var (--card-hover-box-shadow); background-color : var (--btn-bg); } [data-theme=dark] .twikoo .tk-expand :hover { background-color : var (--zhangshier-blue); } [data-theme=dark] .twikoo .tk-expand { border-style : solid; border-width : var (--zhangshier-card-border-width); border-color : var (--zhangshier-card-border); } .tk-input textarea { background-image : url ('https://zhsher.cn/Hexo_img/config/Twikooback.gif' ); min-height : 120px !important ; background-size :10em 10em ; transition : all 0.25s ease-in-out 0s ; } .tk-input textarea :focus { background-position -y: 130px ; transition : all 0.25s ease-in-out 0s }
方案三
.tk-expand { width : 100% ; cursor : pointer; padding : .75em ; text-align : center; transition : all .5s } #twikoo .tk-content p { margin : 0 } #twikoo .tk-expand :hover { color : #fff ; background-color : #3b70fc ; border : 1px solid transparent; } .tk-expand { border : var (--style-border); box-shadow : 0 8px 16px -4px #2c2d300c ; border-radius : 50px ; letter-spacing : 5px ; background-color : var (--zhsher-card-bg) } .tk-replies > .tk-comment { border-top : var (--style-border-dashed); border-radius : 12px ; padding : 1rem 0 0 ; transition : all .3s ease 0s } .tk-replies .tk-content span :first -child:not (.token ) { font-size : .5rem ; color : var (--zhsher-secondtext) } #twikoo pre code { padding : none; background : 0 0 ; color : none; } #twikoo code { padding : 2px 4px ; background : var (--zhsher-secondbg); color : #f47466 } .el-input .el-input--small .el-input-group .el-input-group--prepend :nth-child (1 ):before { content : '输入QQ号会自动获取昵称和头像' ; } .el-input .el-input--small .el-input-group .el-input-group--prepend :nth-child (2 ):before { content : '收到回复将会发送到你的邮箱' ; } .el-input .el-input--small .el-input-group .el-input-group--prepend :nth-child (3 ):before { content : '可以通过昵称访问你的网站' ; } .el-input .el-input--small .el-input-group .el-input-group--prepend :focus -within::after , .el-input .el-input--small .el-input-group .el-input-group--prepend :focus -within::before { display : block } .el-input .el-input--small .el-input-group .el-input-group--prepend ::before { display : none; position : absolute; top : -60px ; white-space : nowrap; border-radius : 10px ; left : 50% ; transform : translate (-50% ); padding : 14px 18px ; background : #444 ; color : #fff } .el-input .el-input--small .el-input-group .el-input-group--prepend ::after { display : none; content : "" ; position : absolute; border : 12px solid transparent; border-top-color : #444 ; left : 50% ; transform : translate (-50% , -48px ) } .vwrap { box-shadow : 2px 2px 5px #bbb ; background : rgba (255 , 255 , 255 , .3 ); border-radius : 8px ; padding : 30px ; margin : 30px 0 30px 0 } .vcard { box-shadow : 2px 2px 5px #bbb ; background : rgba (255 , 255 , 255 , .3 ); border-radius : 8px ; padding : 30px ; margin : 30px 0 0 0 } #twikoo .tk-extra { background : var (--zhsher-card-bg); border : var (--style-border-always); padding : 4px 8px ; border-radius : 8px ; margin-right : 4px ; color : var (--zhsher-secondtext); margin-top : 6px ; font-size : .8rem } #twikoo .tk-extra-text { font-size : .5rem } #twikoo .tk-replies .tk-content { font-size : .9rem } #twikoo .tk-content { margin-top : 0 } .tk-content span a :not ([data-fancybox=gallery] ) { font-weight : 500 ; border-bottom : solid 2px var (--zhsher-lighttext); color : var (--zhsher-fontcolor); padding : 0 .2em ; text-decoration : none } .tk-content span a :not ([data-fancybox=gallery] ):hover { color : var (--zhsher-white); background-color : var (--zhsher-theme); border-radius : 4px } .tk-main .tk-content span > a { border-bottom : none } #post-comment .comment-head { font-size : .8em !important ; margin-bottom : .5rem } .el-input .el-input--small .el-input-group .el-input-group--prepend :focus -within::before { display : block; animation : commonTipsIn .3s } @keyframes commonTipsIn { 0% { top : -50px ; opacity : 0 } 100% { top : -60px ; opacity : 1 } } #twikoo .tk-input .el-textarea__inner { min-height : 130px !important ; border-radius : 15px ; display : block; resize : vertical; padding : 16px 16px 40px 16px ; line-height : 1.5 ; box-sizing : border-box; width : 100% ; font-size : inherit; color : #606266 ; background-color : var (--zhsher-card-bg); border : var (--style-border-always); transition : border-color .2s cubic-bezier (.645 , .045 , .355 , 1 ) } #page .el-textarea__inner { background : var (--zhsher-card-bg) !important ; box-shadow : var (--zhsher-shadow-border); color : var (--zhsher-fontcolor) !important } #twikoo .twikoo .el-input__inner :focus , #twikoo .twikoo .el-textarea__inner :focus { border-color : var (--zhsher-main) } .tk-comments-container > .tk-comment { margin-top : 0 !important ; margin-bottom : 1rem !important ; transition : .3s ; border-radius : 12px ; padding : 0 ; padding-top : 1rem ; border : none; border-top : var (--style-border-dashed) } #post-comment .comment-tips { background-color : rgba (103 , 194 , 58 , .13 ); border : var (--style-border-always); border-color : var (--zhsher-green); color : var (--zhsher-green); border-radius : 8px ; padding : 8px 12px ; margin-top : .5rem ; display : none } #post-comment .comment-tips .show { display : flex } #page .tk-comments-container > .tk-comment { background : var (--zhsher-card-bg); padding : 1rem ; padding-bottom : 1rem ; border : var (--style-border); border-top : var (--style-border); box-shadow : var (--zhsher-shadow-border) } .tk-content { margin-top : .5rem ; overflow : auto; max-height : 500px } .page .el-input__inner { background : var (--zhsher-card-bg) !important } .tk-comments .tk-row-actions-start { position : relative; top : -56px ; left : 17px } .tk-comments .tk-main .tk-row-actions-start { position : relative; top : -56px ; left : 2px } .OwO .OwO-body { border : var (--style-border-always) !important ; border-radius : 8px !important ; overflow : hidden; background-color : var (--zhsher-maskbg) !important ; backdrop-filter : saturate (180% ) blur (10px ); cursor : auto; top : 2.1em !important } @media screen and (max-width : 768px ) { .OwO .OwO-body { width : 260px } .tk-comments .tk-main .tk-row-actions-start { left : 30px } } .OwO .OwO-body .OwO-items .OwO-item :hover { box-shadow : var (--zhsher-shadow-lightblack) !important ; border-radius : 8px } #post-comment .tk-avatar .tk-clickable { margin : 5px } .tk-input textarea { background-image : url ('https://zhsher.cn/Hexo_img/config/Twikooback.gif' ); min-height : 120px !important ; background-size :10em 10em ; transition : all 0.25s ease-in-out 0s ; } .tk-input textarea :focus { background-position -y: 130px ; transition : all 2s ease-in-out 0s !important ; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/twikoo.css">
Twikoo回复邮件模板 原文地址:Twikoo评论回复邮件模板:Acrylic Mail 粉 | 张洪Heo
在前端面板修改配置
<div class="page flex -col"> <div class="box_3 flex -col" style=" display : flex; position : relative; width : 100% ; height : 206px ; background : #ef859d2e ; top : 0 ; left : 0 ; justify-content : center; "><div class="section_1 flex -col" style=" background-image : url ("这里更改为你的网站图标" ); position : absolute; width : 152px ; height : 152px ; display : flex; top : 130px ; background-size : cover; "></div ></div > <div class="box_4 flex -col" style=" margin-top : 92px ; display : flex; flex-direction : column; align-items : center; "> <div class="text-group_5 flex -col justify-between" style=" display : flex; flex-direction : column; align-items : center; margin : 0 20px ; "> <span class="text_1" style=" font-size : 26px ; font-family : PingFang-SC-Bold, PingFang-SC; font-weight : bold; color : #000000 ; line-height : 37px ; text-align : center; ">嘿!你在 ${SITE_NAME} 博客中收到一条新回复。</span > <span class="text_2" style=" font-size : 16px ; font-family : PingFang-SC-Bold, PingFang-SC; font-weight : bold; color : #00000030 ; line-height : 22px ; margin-top : 21px ; text-align : center; ">你之前的评论 在 ${SITE_NAME} 博客中收到来自 ${NICK} 的回复</span > </div > <div class="box_2 flex -row" style=" margin : 0 20px ; min-height : 128px ; background : #F7F7F7 ; border-radius : 12px ; margin-top : 34px ; display : flex; flex-direction : column; align-items : flex-start; padding : 32px 16px ; width : calc (100% - 40px ); "> <div class="text-wrapper_4 flex -col justify-between" style=" display : flex; flex-direction : column; margin-left : 30px ; margin-bottom : 16px ; "> <span class="text_3" style=" height : 22px ; font-size : 16px ; font-family : PingFang-SC-Bold, PingFang-SC; font-weight : bold; color : #C5343E ; line-height : 22px ; ">${PARENT_NICK}</span > <span class="text_4" style=" margin-top : 6px ; margin-right : 22px ; font-size : 16px ; font-family : PingFangSC-Regular, PingFang SC; font-weight : 400 ; color : #000000 ; line-height : 22px ; ">${PARENT_COMMENT}</span > </div ><hr style=" display : flex; position : relative; border : 1px dashed #ef859d2e ; box-sizing : content-box; height : 0px ; overflow : visible; width : 100% ; "><div class="text-wrapper_4 flex -col justify-between" style=" display : flex; flex-direction : column; margin-left : 30px ; "> <hr> <span class="text_3" style=" height : 22px ; font-size : 16px ; font-family : PingFang-SC-Bold, PingFang-SC; font-weight : bold; color : #C5343E ; line-height : 22px ; ">${NICK}</span > <span class="text_4" style=" margin-top : 6px ; margin-right : 22px ; font-size : 16px ; font-family : PingFangSC-Regular, PingFang SC; font-weight : 400 ; color : #000000 ; line-height : 22px ; ">${COMMENT}</span > </div > <a class="text-wrapper_2 flex -col" style=" min-width : 106px ; height : 38px ; background : #ef859d38 ; border-radius : 32px ; display : flex; align-items : center; justify-content : center; text-decoration : none; margin : auto; margin-top : 32px ; " href="${POST_URL}"> <span class="text_5" style=" color : #DB214B ; ">查看详情</span > </a > </div > <div class="text-group_6 flex -col justify-between" style=" display : flex; flex-direction : column; align-items : center; margin-top : 34px ; "> <span class="text_6" style=" height : 17px ; font-size : 12px ; font-family : PingFangSC-Regular, PingFang SC; font-weight : 400 ; color : #00000045 ; line-height : 17px ; ">此邮件由评论服务自动发出,直接回复无效。</span > <a class="text_7" style=" height : 17px ; font-size : 12px ; font-family : PingFangSC-Regular, PingFang SC; font-weight : 400 ; color : #DB214B ; line-height : 17px ; margin-top : 6px ; text-decoration : none; " href="${SITE_URL}">前往博客</a > </div > </div > </div >
底部徽标美化 原文地址:徽标 | Akilarの糖果屋
徽标我使用shields.io 在线生成,没有使用插件。Akilar的插件有动画效果,可以试一试!
shields.io格式:https://img.shields.io/badge/左侧文字-右侧文字-色值?style=flat&logo=xxx,色值支持十六进制、rgb、rgba、hsl、hsla,中文及符号需要转义字符对照表
logo设定:logo图标查询 ,如果没有对应图标可以使用在线图片转BASE64
html写好后,通过在线HTML压缩 将<body>中的内容压缩(不包括body),之后在主题配置文件_config.butterfly.yml中引入
footer: - custom_text: + custom_text: 压缩的html代码
附我的模板,建议将徽标图片在网页中保存到博客路径中,而不是使用url,因为shields访问速度慢
<!DOCTYPE html > <html > <head > <meta charset ="utf-8" > <title > </title > </head > <body > <div > 满地都是六便士 我想抬头看月亮</div > <p > <a style ="margin-inline:5px" target ="_blank" href ="https://beian.miit.gov.cn/#/Integrated/index/" > <img src ="https://img.shields.io/badge/%E6%99%8BICP%E5%A4%87-2022005322%E5%8F%B7--1-e1d492?style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+nhxg7wAACNlJREFUSInF1mmMVeUdx/Hv2e+5+519mJWBYQZkGxZZxLKJqBXGoLS1iXWrmihotFXaJiTWWlsbl6q1aetWd5u0VkKjNG4YEJSlOCibDLMwM8x679z9nnPP1jcVJUxf+7z6J8+LT37/Z4VvaQhfFS8+sBXbctCDGrVTKlBUH4mxAbI9Hfj0IJLsp6paJ5/tmn20N/D0wKDRMq9F/c3M2U1/V0vDfWMFh+tv/Ig1zYPMabDImPJ52OaXO87W580KggCiiOsJOJ6I3wcNFaaeNKxrt72f2fLGu4FpJ/sDQABRzD22fH7/Yze069vGc6mrDLNIJCDik10sxz2by3VdPM87xzkP9jwPTZFRVI1YUJKH+oy7n3tbvv/P2wW/UQxRWe6w4ZJRptYLHDoCuz8v5cP92XbI762O+h6UVWHnUFbPpU0fEb2A60mMJ7MUi9b/b7UgKhiZMaIxm8YLplLMDPz8hl/EH+rs8TNlUpFf32uyZJGLPDwCiTGUyTWodTN49eUCdz2YwXb9NNcObp1X98WDoufynzMVCEKGn27ayPTWBi5ad8P5iQUkJEnFLjqM9Z+hrVX0vfDe6K2dPRWsW2bwyp9EUifSJB84gdxrkR0eRgv1o/3I4fbbprJ6scqamzVO9pffec1S5ZWY2Nfz5qEy/FqOC2Y3s3j53HMSi18VRjFPwSwg+1RfVbl115vvJrsfej7UGIsYPPGgQ7JXoO+Xx5B3dHEomyJ9x1qiQozkr95h5937aFnVyouPlgJK+Ss7Fxz64OTSxSX+LHYxT2IsRW5kbGI4oHcR0jqoqTjV9se3I7/f8rS/ClS23GxSXhph6L5d9Akm7qqZhHWBQGUJ+CWGFzcg7e7m6D3/ZuW1Ea5YKdA3EojuONi813TqNi+YPYOKUhXDtCeGL26/hakLLiEcdsaHRkRAoLRc4fJrmhnekyF0apgZowWSwwkaa+rw3f8WA1GZZsPP5JEChX8dhZTN6iU6kAcs5s+dHd183SJ0VVKL57pfw6YdRQw23aeWTns47DPTALWlRTR7kMLew6hGgYqUhWXYFFUdPZ6lUBahLA8hVcOftckfi7No7VRAAQqsX1dybfvG1qwriM9mM5mJ4e4jO5Cc01dPqixbr8tWGBQUL4vjGigEEShi+xUmZ2RiR/sJ1pbS8NkgZrKAGw0TsgQsQyFaF/nfYTGprAlMFysbA1pI3mhkR6snhGsaymYGvPyFEb9IdbUE2AzFFTwpRqCtBY0wmdER+hZW4j63gcJj38V+/ErSUZXsYBfjIZHIRW0c2Z8BskCAqN+CbBJBFnyyKjR+Ez57nBxLqpfMUeSISElMBFz6x2Q6OxzWrYjyxWVzEewioU3LCS5vQY6nMUrLwNaxXvoQ59IloFSx54PPAZtQLExVZZDxsVE8J4dn6v4JYatgbSjk0owPw7RGH2ADMo88Z7L20ip8f7gC7fAo0q4+0rt7kEQDvaghVZbiPHUHcyeXcfLjT3jmpR7AYsnSScya3UR8bARVMck7Y/cB75/X6rDf3Fg2dw2jKZm5dXGm1LuAzO5DCo9v6aT0ibco5kzOvLOP+NGTFJtDpPYeZKijk/Rn3QxsfZV7txwhX7ABiZUXBsGvIvguQApNQQva9RMmTvZ2dpVUls+tX/UD7GN/Y8Ws05w6rQF+9vyzg1vZjbvMRJhXiRSU8DpTFFe0QE8S6SfPkOkZoktrB2oAhZWrwljxOPmchiSMYOWNoxNuruFU5vWeXdsojiUon345113dBBQBmTYlTimgdB8nfPo4WjaNFgN9OMEkJ02dnadVt5ki54Esqy+bzKJltVhSPbI3iN2zCyMTeXNCuG7Omm2Zok7PR2+R7jvD8ouruHhmCrB5jVZeYxLdrTP4sr4Vtd9g4MA4qc4c+6cu5NPamfw4P59t2WrA4YdXKkASf7SFivo6PDdEPmf1fRM++zp1bH/0r4I1dD1ODtOWaW4IsvPjL7nqXhloQiSPwjjgMYkMASyGEBkjhISCQwkwzve/18AbT+pk8pVY4UacQi9y+gyZ0eRAw4qHa89LXEx1LXMSPfhDJYRb59BtlLKg2WPT2l6qYl1svtGkrLYckyA1S+t5+2ATm37WCui0LSynsckDNH5zTxAchbQtkx08hDHYiW6NgC0enHBzEZ102UDH8QORdEckjEzZrNWkRydzyx17uGnDXqbUnGZ6dRPjSY91q2TqwjFuvTxLo5Zn5Qo/pumRSFcTLQtybEhGE0fQrDhhJ0VvH2lTnnHPhGtsmWan469apERjI2MH3qN7+7MEfH6ql29CbV7PvsMG32k6yU2XDhEKyZw66eJaRdrXR7CzCcqUNC3zwgymPJRCH4KRRLINimpL14A5Y4GDeOqbsPRVcfuN7Xj44pav/hFfrNT2kr2rsqf2Ibp5pEA14ZIImUyW3t5REkkTXRGQ/DGGhtLginhqCWknQDE5hKf5UFSF9Lj020Q2ul5V1AR2hr+8vuP8Vlc2zMPRxoSjnx7XBC14sDoydahSGq7KdO/HFyrBchxCVfX4fDKp4T7SCQejYODZLrYgIqgKFsNIgQqEYob8mW6yiUyb7Z64LVK/+B85xznnJ3AWzqTzuIX46mr5wLs+UUTyIriBCjRNxguHMJIFDLEEvXEOVRWnSJ0+jCd4CJoGjoedM1CLcXQziW3nMV2TSMBeOx7vWZvPt1r+cMPzE8KunaUkFn0vNrvtqXj34c1W6gzxlEQ6naIoBahtnkMwoFMwIVzSRNguMt53Aj2s4nkSlgPoGqLkICsRNF0gl8rYWuP8+11/w/OOJDEhHPKLCIpOXmi+M9AgP+maiesLifF2T1Rn5ZNj5Lo/Qc/GcPMmhdoqlEgIGzCK4PiCmJKK68p4KfF3qYGuF0qCRUkJTzleUbvQyWRTuE5xYthxQbBs7EISAbkzUFG3VfXXbK2YFi3X/eryfKKnqVBItNjJxDzH8erddC4SqWwcN5WyTtlyO1RP/Lh3eHD76MB40swmiDVJyDLYRhpc5+ub6tse/wWKbvSQEAw1awAAAABJRU5ErkJggg== " title ="ICP备案" > </a > <a style ="margin-inline:5px" target ="_blank" href ="https://hexo.io/" > <img src ="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&logo=hexo" title ="博客框架为Hexo" > </a > <a style ="margin-inline:5px" target ="_blank" href ="https://butterfly.js.org/" > <img src ="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAXCAMAAADX9CSSAAABnlBMVEUAAAAYERBJLh1JJBTeu7EjEgo5HRRaHjwxIBsaEQ4dHSEeOUjZ2dk8JBs0Mzza3dodExQcFhIZNVBfNyxXQjBWTklxaWRAX3EkEgZWHEwiEQAZZIgPDxIUOFhAOzYobpQ8orkjXoJHoLjJyclBdYokJCE7PUItKyxFSVE4obJQPStAkp80s8pAJBMcWHUOJUERFBgQAAAfNEoPIzsndpklIi0gIi4SFBkcP2wcVXAcQnEmTWomcZkoT20sZY4uOD8fHR4pVnopVnlDbHM6kqIziJmqqqUnoPg1zP8vyP84vf8/wf8xw/8ltP9L4v8lv/8wz/8nzv4bVpop2f8xy/8osf440P8u5P8mk/QjjPUvfKojp/EchdIyu/Ahbs0YXqIio/8pxP8qxvs5wvgnh94lsP1C0f9A6/87xP4puv8lqP1Czf8znO1Ax/8KDQs7qv8ldKsnxv8ulcI64/ImpNw75P8s9P8tuP0sPkotjc4oKz8nrPMhme4gluomdZ1B3f84sf9Crtgtfa4tYYw4sv9CrdUuZJJB3P8kbNEjb9U867bWAAAAR3RSTlMAxTQTEU0fAidq1OoDG2MYdYfmF8bLTsr9CQ/p1PhE6fL+9gnlq4+KH8p0d9vj/fj3P+H267m99MH5xoz+lONNu9PS5vrxNhiY9jsAAAGGSURBVHhefY/VbuMAEEXHiWs7YIeZysyMi2AOMzOUmXn5r3fXTtT2oXuk0Ujn4d4ZeA3tMEHiLxVJDGthSG18P6h4ZhWDH4zqIXi3u8899FMAWpCG6v/O7+8igCFf93b8vRTo+qBPB1Svf2fvB0IAKDTb91v+7rcoCijq7fZvfdvWSLkDaZ6vN0ZMOtCZRhp1nn8ckIpUPRzX/Hk0hn5Bx47umhzXo5L9usAGmZNxq8U6fsIEWeFW9jMrQjTInl3ZJmxXZ2wwKkx2SR7T5BgmGvt9ab/8FYsyTE5DSB5X+SrxOHtxbj+/YOPxyry+/X+XqxxJJE4/2T+fJhKRskuOAWw2UwpFIqGPE7Z/q5QxyjmKuRsxEDo4tpgtxwehgHg95ZW8Q53drLUCh2ar+TDQqm1m1UqQMBSKdExMj8JoWozRxYKh0+tJ0TTtIwB783cnPe1eULrDqWR1Awd8rZpMhd2mtsdVS+H8KgkA5HI+PK13QAc9sijfhi0gBngCdyo7mU4c/scfy35OuevmbR0AAAAASUVORK5CYII= " title ="主题采用butterfly" > </a > <a style ="margin-inline:5px" target ="_blank" href ="https://cloud.tencent.com/ " > <img src ="https://img.shields.io/badge/Hosted-腾讯云-0cedbe?style=flat&logo=iCloud" title ="本站采用双线部署,国内线路托管于腾讯云" > </a > <a style ="margin-inline:5px" target ="_blank" href ="https://github.com/" > <img src ="https://img.shields.io/badge/Source-Github-d021d6?style=flat&logo=GitHub" title ="本站采用双线部署,国外线路托管于Github" > </a > <a style ="margin-inline:5px" target ="_blank" href ="http://creativecommons.org/licenses/by-nc-sa/4.0/" > <img src ="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&logo=Claris" title ="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可" > </a > </p > </body > </html >
一图流 原文地址:
小张采用店长方案
修改主题配置文件_config.butterfly.yml,background配置项,设置全局背景
background: url(http://xxxxxx.com/xxx.jpg)
新建[BlogRoot]/source/css/bg.css
#footer { background : transparent!important ; } #footer ::before { background : transparent!important ; } #page-header { background : transparent!important ; } #page-header ::before { background : transparent!important ; } #page-header .post-bg :before { background-color : transparent!important ; } [data-theme="dark" ] #footer ::before { background : transparent!important ; } [data-theme="dark" ] #page-header ::before { background : transparent!important ; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/bg.css">
夜间模式繁星 原文地址:Hexo博客夜间模式繁星(宇宙)效果 | Leonus
新建[BlogRoot]/source/js/universe.js
function dark ( ) { window .requestAnimationFrame = window .requestAnimationFrame || window .mozRequestAnimationFrame || window .webkitRequestAnimationFrame || window .msRequestAnimationFrame ; var n, e, i, h, t = .05 , s = document .getElementById ("universe" ), o = !0 , a = "180,184,240" , r = "226,225,142" , d = "226,225,224" , c = []; function f ( ) { n = window .innerWidth , e = window .innerHeight , i = .216 * n, s.setAttribute ("width" , n), s.setAttribute ("height" , e) } function u ( ) { h.clearRect (0 , 0 , n, e); for (var t = c.length , i = 0 ; i < t; i++) { var s = c[i]; s.move (), s.fadeIn (), s.fadeOut (), s.draw () } } function y ( ) { this .reset = function ( ) { this .giant = m (3 ), this .comet = !this .giant && !o && m (10 ), this .x = l (0 , n - 10 ), this .y = l (0 , e), this .r = l (1.1 , 2.6 ), this .dx = l (t, 6 * t) + (this .comet + 1 - 1 ) * t * l (50 , 120 ) + 2 * t, this .dy = -l (t, 6 * t) - (this .comet + 1 - 1 ) * t * l (50 , 120 ), this .fadingOut = null , this .fadingIn = !0 , this .opacity = 0 , this .opacityTresh = l (.2 , 1 - .4 * (this .comet + 1 - 1 )), this .do = l (5e-4 , .002 ) + .001 * (this .comet + 1 - 1 ) }, this .fadeIn = function ( ) { this .fadingIn && (this .fadingIn = !(this .opacity > this .opacityTresh ), this .opacity += this .do ) }, this .fadeOut = function ( ) { this .fadingOut && (this .fadingOut = !(this .opacity < 0 ), this .opacity -= this .do /2 ,(this .x >n||this .y <0 )&&(this .fadingOut =!1 ,this .reset ()))},this .draw =function ( ){if (h.beginPath (),this .giant )h.fillStyle ="rgba(" +a+"," +this .opacity +")" ,h.arc (this .x ,this .y ,2 ,0 ,2 *Math .PI ,!1 );else if (this .comet ){h.fillStyle ="rgba(" +d+"," +this .opacity +")" ,h.arc (this .x ,this .y ,1.5 ,0 ,2 *Math .PI ,!1 );for (var t=0 ;t<30 ;t++)h.fillStyle ="rgba(" +d+"," +(this .opacity -this .opacity /20 * t) + ")" , h.rect (this .x - this .dx / 4 * t, this .y - this .dy / 4 * t - 2 , 2 , 2 ), h.fill () } else h.fillStyle = "rgba(" + r + "," + this .opacity + ")" , h.rect (this .x , this .y , this .r , this .r ); h.closePath (), h.fill () }, this .move = function ( ) { this .x += this .dx , this .y += this .dy , !1 === this .fadingOut && this .reset (), (this .x > n - n / 4 || this .y < 0 ) && (this .fadingOut = !0 ) }, setTimeout (function ( ) { o = !1 }, 50 ) } function m (t ) { return Math .floor (1e3 * Math .random ()) + 1 < 10 * t } function l (t, i ) { return Math .random () * (i - t) + t } f (), window .addEventListener ("resize" , f, !1 ), function ( ) { h = s.getContext ("2d" ); for (var t = 0 ; t < i; t++) c[t] = new y, c[t].reset (); u () }(), function t ( ) { document .getElementsByTagName ('html' )[0 ].getAttribute ('data-theme' ) == 'dark' && u (), window .requestAnimationFrame (t) }() }; dark ()
新建[BlogRoot]/source/css/universe.css
#universe { display : block; position : fixed; margin : 0 ; padding : 0 ; border : 0 ; outline : 0 ; left : 0 ; top : 0 ; width : 100% ; height : 100% ; pointer-events : none; z-index : 1 ; } @media screen and (max-width : 768px ) { #universe { display : none; } } [data-theme='light' ] #universe { display : none; }
修改主题配置文件_config.butterfly.yml,引入css、js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/universe.css"> bottom: # - <script src="xxxx"></script> + - <canvas id="universe"></canvas> # 创建画布 + - <script async src="/js/universe.js"></script> # 引入js
友链申请按钮 Leonus 控制台爬的
新建[BlogRoot]/source/css/applybutton.js
function linkCom (type ) { var n = document .querySelector (".el-textarea__inner" ) if (type == 'bf' ) { n.value = '```yml\n' ; n.value += `- name: link: avatar: descr: ` ; n.value += '\n```' ; n.setSelectionRange (15 , 15 ); } else { n.value = '```yml\n' ; n.value += `站点名称: 站点地址: 头像链接: 站点描述:` ; n.value += '\n```' ; n.setSelectionRange (5 , 5 ); } n.focus (); }
新建[BlogRoot]/source/css/applybutton.css
.addBtn button :hover { background : #da6c7d ; color : white; } [data-theme=dark] .addBtn button :hover { background : #96a7be ; } .addBtn { display : flex; justify-content : center; flex-wrap : wrap; } .addBtn i { font-size : 1.3rem ; margin-right : 10px ; } .addBtn button { transtion: .2s ; display : flex; margin : 5px auto; color : var (--global-bg); padding : 15px ; border-radius : 12px ; background : var (--search-result-title); align-items : center; }
修改主题配置文件_config.butterfly.yml,引入css、js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/applybutton.css"> bottom: # - <script src="xxxx"></script> + - <script async src="/js/applybutton.js"></script>
[BlogRoot]/source/link/index.md底部插入
<div class ="addBtn" > <button onclick ="linkCom()" > <i class ="fa-solid fa-circle-plus" > </i > 快速申请 (默认样式)</button > <button onclick ="linkCom('bf')" > <i class ="fa-solid fa-circle-plus" > </i > 快速申请 (Butterfly)</button > </div >
控制台彩蛋 原文地址:console的高级用法 | 安知鱼
新建[BlogRoot]/source/js/print.js
var now1 = new Date ()function createtime1 ( ) { var grt = new Date ('05/01/2022 00:00:00' ) now1.setTime (now1.getTime () + 250 ) var days = (now1 - grt) / 1000 / 60 / 60 / 24 var dnum = Math .floor (days) var ascll = [ `欢迎来到张时贰\`Blog!` , `洞庭春溜满,平湖锦帆张,称小张。十二为一年亦半天亦...家人、恋人、朋友...安好、知心、快乐...十二画,时间、人、情绪,十二是我最喜欢的数字,故称张时贰!` , ` ██╗ ██╗██╗ ██████╗ ██╗ ███████╗████████╗ ██║ ██║██║██╔═══██╗██║ ██╔════╝╚══██╔══╝ ██║ ██║██║██║ ██║██║ █████╗ ██║ ╚██╗ ██╔╝██║██║ ██║██║ ██╔══╝ ██║ ╚████╔╝ ██║╚██████╔╝███████╗███████╗ ██║ ╚═══╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═╝ ` , '张时贰`Blog 已上线' , dnum, '天' , '©2022 By 张时贰' , ] setTimeout ( console .log .bind ( console , `\n%c${ascll[0 ]} %c ${ascll[1 ]} %c ${ascll[2 ]} %c${ascll[3 ]} %c ${ascll[4 ]} %c ${ascll[5 ]} \n\n%c ${ascll[6 ]} \n` , 'color:#425aef' , '' , 'color:#425aef' , 'color:#425aef' , '' , 'color:#425aef' , '' ) ) } createtime1 ()function createtime2 ( ) { var ascll2 = [`NCC2-036` , `调用前置摄像头拍照成功,识别为【小笨蛋】.` , `Photo captured: ` , ` 🤪 ` ] setTimeout ( console .log .bind ( console , `%c ${ascll2[0 ]} %c ${ascll2[1 ]} %c \n${ascll2[2 ]} %c\n${ascll2[3 ]} \n` , 'color:white; background-color:#4fd953' , '' , '' , 'background:url("https://q1.qlogo.cn/g?b=qq&nk=1310446718&s=5") no-repeat;font-size:450%' ) ) setTimeout ( console .log .bind ( console , '%c WELCOME %c 你好,小笨蛋.' , 'color:white; background-color:#4f90d9' , '' ) ) setTimeout ( console .warn .bind ( console , '%c ⚡ Powered by 张时贰 %c 你正在访问 张时贰 的博客.' , 'color:white; background-color:#f0ad4e' , '' ) ) setTimeout ( console .log .bind ( console , '%c W23-12 %c 你已打开控制台.' , 'color:white; background-color:#4f90d9' , '' ) ) setTimeout ( console .warn .bind ( console , '%c S013-782 %c 你现在正处于监控中.' , 'color:white; background-color:#d9534f' , '' ) ) } createtime2 ()console .log = function ( ) {}
修改主题配置文件_config.butterfly.yml,引入js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> bottom: # - <script src="xxxx"></script> + - <script async src="/js/print.js"></script>
动态title 新建[BlogRoot]/source/js/title.js
var OriginTitile = document .title ; var titleTime;document .addEventListener ('visibilitychange' , function ( ){ if (document .hidden ){ document .title = '404 Not Found' ; clearTimeout (titleTime); }else { document .title = 'ヾ(≧▽≦*)o上当了吧嘿嘿' ; titleTime = setTimeout (function ( ) { document .title = OriginTitile ; }, 3000 ); } });
修改主题配置文件_config.butterfly.yml,引入js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> bottom: # - <script src="xxxx"></script> + - <script async src="/js/title.js"></script>
鼠标样式 自己制作ico格式 图片或者下载致美化 cur格式 文件存放在[BlogRoot]/source/css
新建[BlogRoot]/source/css/curtor.css
body { cursor : url (close.ico ), default; } a ,img { cursor : url (open.ico ), default; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/cursor.css">
全站变灰 原文地址:Custom Beautify | Akilarの糖果屋
有时候一些哀悼日、纪念日需要变灰时使用
新建[BlogRoot]/source/js/gray.js
方案一:店长方案,通过JS在特定日期变灰
if(PublicSacrificeDay()){ document.getElementsByTagName ("html ")[0] .setAttribute ("style","filter :gray !important ;filter :grayscale (100% );-webkit-filter :grayscale (100% );-moz-filter :grayscale (100% );-ms-filter :grayscale (100% );-o-filter :grayscale (100% );"); } function PublicSacrificeDay(){ var PSFarr=new Array("0403 ","0404 ","0405 ","0406 ","0414 ","0512 ","0707 ","0807 ","0814 ","0909 ","0918 ","0930 ","1025 ","1213 "); //2020 年4 月4 日 新冠肺炎哀悼日,清明节 //2010 年4 月14 日,青海玉树地震 //2008 年5 月12 日,四川汶川地震 //1937 年7 月7 日,七七事变 又称卢沟桥事变 //2010 年8 月7 日,甘肃舟曲特大泥石流 //8 月14 日,世界慰安妇纪念日 //1976 年9 月9 日,毛主席逝世 //1931 年9 月18 日,九一八事变 //烈士纪念日为每年9 月30 日 //1950 年10 月25 日,抗美援朝纪念日 //1937 年12 月13 日,南京大屠杀 var currentdate = new Date(); var str = ""; var mm = currentdate.getMonth ()+1 ; if(currentdate.getMonth ()>9 ){ str += mm; }else{ str += "0 " + mm; } if(currentdate.getDate ()>9 ){ str += currentdate.getDate (); }else{ str += "0 " + currentdate.getDate (); } if(PSFarr.indexOf (str)>-1 ){ return 1 ; }else{ return 0 ; } }
修改主题配置文件_config.butterfly.yml,引入js文件
inject: bottom: + - <script async src="/css/gray.js"></script>
方案二:在需要时手动加入
新建[BlogRoot]/source/js/gray.css
html { -webkit-filter : grayscale (100% ); filter : progid:DXImageTransform.Microsoft.BasicImage (graysale=1 ); }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/gray.css">
方案三:电脑不在跟前且是服务器部署,修改nginx配置文件(不知道配置文件位置可以借助宝塔,参考网站监控 中图文说明)
http { …… sub_filter '</head>' '<style type="text/css">html { -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); -ms-filter: grayscale(100%); -o-filter: grayscale(100%); filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1); filter: gray;}</style></head>' ; sub_filter_types *; sub_filter_once off ; }
黑幕 原文地址:简单、快速地实现萌娘百科黑幕效果 - Initial_heart’s Blog
新建[BlogRoot]/source/css/dark span.css
.heimu ,.heimu rt{ background-color :gray; } .heimu ,.heimu a ,a .heimu ,a .new .heimu ,span .heimu a .new ,span .heimu a .external ,span .heimu a .external :visited ,span .heimu a .extiw ,span .heimu a .extiw :visited ,span .heimu a .mw-disambig ,span .heimu a .mw-redirect { transition :color 0.13s linear; color :gray; text-shadow :none; } span .heimu :hover ,span .heimu :active { color :white; } span .heimu :hover a ,a :hover span .heimu { color :lightblue; } span .heimu :hover a :visited ,a :visited :hover span .heimu { color :#C5CAE9 ; } span .heimu :hover a .new ,a .new :hover span .heimu { color :#FCC ; } span .heimu a .new :hover :visited ,a .new :hover :visited span .heimu { color :#EF9A9A ; } span .heimu :hover a .extiw :visited ,a .extiw :visited :hover span .heimu { color :#D1C4E9 ; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/dark span.css">
访客统计与信息 首先注册申请51la,拿到统计代码,可参考51la统计体验报告:很全面的惊喜,Butterfly适配51la统计 | 张洪Heo
原文地址:
主题文档:
访问统计侧边栏 新建[BlogRoot]/source/_data/widget.yml
bottom: - class_name: id_name: name: 访问统计 icon: iconfont icon-tongji order: 1 html: <link rel="stylesheet" href="/css/visitor.css"><div id="visitor"><div class="content"></div></div><script src="/js/visitor.js"></script>
新建[BlogRoot]/source/js/visitor.js,注意修改51la地址
fetch ('https://v6-widget.51.la/v6/xxxxxxxxxxxxxx/quote.js' ).then (res => res.text ()).then ((data ) => { let title = ['最近活跃访客' , '今日访问人数' , '今日访问量' , '昨日人数' , '昨日访问量' , '本月访问量' , '总访问量' ] let num = data.match (/(?<=<\/span><span>).*?(?=<\/span><\/p>)/g ) let s = document .querySelectorAll ('#visitor .content' )[0 ] if (s !== undefined ) { for (let i = 0 ; i < num.length ; i++) { if (i == 3 || i == 4 ) continue ; s.innerHTML += '<div><p><span id=name>' + title[i] + '</span><span class="num">' + num[i] + '</span></p></div>' } } });
新建[BlogRoot]/source/css/visitor.css
#visitor { box-sizing : border-box !important ; margin : 0px !important ; font-size : 18px !important ; line-height : 1.7 !important ; color : rgb (51 , 51 , 51 ) !important ; background-color : rgb (255 , 255 , 255 ) !important ; padding : 16px 0px !important ; border : 1px solid rgb (255 , 255 , 255 ) !important ; height : auto !important ; } #visitor div p { margin : 0px !important ; text-align : left !important ; } #visitor div #name { color : rgb (137 , 137 , 137 ) !important ; display : inline-block !important ; } #visitor div .num { color : rgb (51 , 51 , 51 ) !important ; font-weight : bold !important ; float : right !important ; }
修改主题配置文件_config.butterfly.yml,引入css、js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/visitor.css"> bottom: # - <script src="xxxx"></script> + - <script src="/js/visitor.js"></script>
访客信息 效果预览:关于 | 心流
只需在md文件中插入
## 博客统计 ### 访客统计 <div id ="pvisitor" > <div class ="content" > </div > </div > ### 访客信息 <div id ="ivisitor" > <div class ="content" > </div > </div > <link rel ="stylesheet" href ="/css/visitor.css" > <script > fetch ('https://v6-widget.51.la/v6/xxxxxxxxxxxxxx/quote.js' ).then (res => res.text ()).then ((data ) => { let title = ['最近活跃访客' , '今日访问人数' , '今日访问量' , '昨日人数' , '昨日访问量' , '本月访问量' , '总访问量' ] let num = data.match (/(?<=<\/span><span>).*?(?=<\/span><\/p>)/g ) let s = document .querySelectorAll ('#pvisitor .content' )[0 ] for (let i = 0 ; i < num.length ; i++) { if (i == 3 || i == 4 ) continue ; s.innerHTML += '<div><span>' + title[i] + '</span><span class="num">' + num[i] + '</span></div>' } }); fetch ('https://api.vvhan.com/api/visitor.info' ).then (res => res.json ()).then ((data ) => { let c = document .querySelectorAll ('#ivisitor .content' )[0 ] var system = data['system' ] var addr = data['location' ] var ipaddr = data['ip' ] var weather = data['tq' ]+" " +data['high' ].replace ("最低 " ,"" )+"~" +data['high' ].replace ("最高 " ,"" ) var tip = data['tip' ] system = system==="未知操作系统" ?"移动端" :system addr = addr===null ?"未知" :addr ipaddr = ipaddr===null ?"未知" :ipaddr weather = weather===null ?"未知" :weather tip = tip===null ?"未知" :tip c.innerHTML = `<div><span>系统</span><span class="num">${system} </span></div> <div><span>地址</span><span class="num">${addr} </span></div> <div><span>IP地址</span><span class="num">${ipaddr} </span></div> <div><span>天气</span><span class="num">${weather} </span></div> <div><span>温馨提示</span><span class="num"> <div style="width:100% !important"><span style="font-size:1.5rem;font-weight:bold;display:block;">${tip} </span></div> </span></div> ` }); </script >
新建[BlogRoot]/source/css/ivisitor.css
#pvisitor ,#ivisitor { font-size : 18px ; padding : 20px ; border-radius : 12px ; width : 100% ; color : var (--font-color); background-color : var (--card-bg); } div #pvisitor .content ,div #ivisitor .content { display : flex; flex-wrap : wrap; justify-content : space-between; } div #pvisitor a ,div #ivisitor a { text-decoration : none; } #pvisitor .content div ,#ivisitor .content div { display : inline-block; } #pvisitor div span ,#ivisitor div span { font-size : 14px ; line-height : 1.3 ; display : block; } #pvisitor div .num ,#ivisitor div .num { letter-spacing : 1px ; font-weight : bold; font-size : 1.6rem ; margin-bottom : .8rem ; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/ivisitor.css">
访客统计&访客信息合并版 我想把访客统计和访客信息合并在一起,对心流的方案进行了更改,主要变更了innerHTML结构及css样式
新建[BlogRoot]/source/_data/widget.yml
bottom: - class_name: id_name: name: 你好呀 icon: fa-solid fa-child order: 1 html: <link rel ="stylesheet" href ="/css/visitor.css" > <div id ="visitor" > <div class ="content" > </div > </div > <div id ="visitor" > <div class ="content" > </div > </div > <script src ="/js/visitor.js" > </script >
新建[BlogRoot]/source/css/visitor.css
#visitor { box-sizing : border-box !important ; margin : 0px !important ; font-size : var (--global-font-size); line-height : 1.7 !important ; color : rgb (51 , 51 , 51 ) !important ; height : auto !important ; } #visitor div p { margin : 0px !important ; text-align : left !important ; } #visitor div #name { color : rgb (137 , 137 , 137 ) !important ; display : inline-block !important ; } #visitor div .num { color : rgb (51 , 51 , 51 ) !important ; letter-spacing : 1px ; font-weight : bold; float : right !important ; }
新建[BlogRoot]/source/js/visitor.js,注意修改51la地址
fetch ('https://api.vvhan.com/api/visitor.info' ).then (res => res.json ()).then ((data ) => { let c = document .querySelectorAll ('#visitor .content' )[0 ] var system = data['system' ] var addr = data['location' ] var ipaddr = data['ip' ] var weather = data['tq' ] + " " + data['high' ].replace ("最低 " , "" ) + "~" + data['high' ].replace ("最高 " , "" ) var tip = data['tip' ] var f1 = data['fl' ] system = system === "未知操作系统" ? "移动端" : system addr = addr === null ? "未知" : addr ipaddr = ipaddr === null ? "未知" : ipaddr weather = weather === null ? "未知" : weather tip = tip === null ? "未知" : tip f1 = f1 === null ? "未知" : f1 c.innerHTML = `<div><p><span id=name>系统</span><span class="num">${system} </span></p></div> <div><p><span id=name>地址</span><span class="num">${addr} </span></p></div> <div><p><span id=name>IP地址</span><span class="num">${ipaddr} </span></p></div> <div><p><span id=name>天气</span><span class="num">${weather} </span></p></div> <div><p><span id=name>风级</span><span class="num">${f1} </span></p></div> <div><p><span id=name>温馨提示</span><span class="num"> <div style="width:100% !important"><span style="font-weight:bold;display:block;">${tip} </span></div> </p></span></div> ` }); fetch ('https://v6-widget.51.la/v6/xxxxxxxxxx/quote.js' ).then (res => res.text ()).then ((data ) => { let title = ['最近活跃访客' , '今日访问人数' , '今日访问量' , '昨日人数' , '昨日访问量' , '本月访问量' , '总访问量' ] let num = data.match (/(?<=<\/span><span>).*?(?=<\/span><\/p>)/g ) let s = document .querySelectorAll ('#visitor .content' )[1 ] if (s !== undefined ) { for (let i = 0 ; i < num.length ; i++) { if (i == 3 || i == 4 ) continue ; s.innerHTML += '<div><p><span id=name>' + title[i] + '</span id=name><span class="num">' + num[i] + '</span></p></div>' } } });
顶部卡片 来源:Leonus - 进一寸有进一寸的欢喜 控制台扒的
Heo哥、Leonus、安知鱼等朋友圈、即刻短文等顶部都有一张卡片,蛮不错,所以扒了一下
在需要使用的页面顶部插入
<!-- 顶部卡片 --> <div class ="page-top-card" style ="background-image: url(https://图片地址);" > <div class="content-item-tips">动态</div> <span class="content-item-title">空间说说</span> <div class="content-bottom"> <div class="tips">我的生活、吐槽、闲话...</div> <a class="banner-button" href="https://www.cn"> <i class="fa-solid fa-image"></i><span>关于我</span> </a> </div> </div> <style type="text/css"> #page-header.not-home-page { height: 50px; } div#page-site-info { display: none; } .page-top-card { background-size: cover; background-position: center; height: 20rem; padding: 10px 2.7rem; border-radius: 20px; color: #fff; position: relative } span.content-item-title { font-size: 2.3em; font-weight: 700; line-height: 1.2 } .content-bottom { display: flex; justify-content: space-between; align-items: center; position: absolute; width: calc(100% - 5.4rem); bottom: 1rem } a.banner-button { cursor: pointer; color: #fff !important; backdrop-filter: saturate(180%) blur(20px); background: rgb(120 120 120 / 30%); padding: 5px 15px; border-radius: 100px; text-decoration: none !important } a.banner-button i { margin-right: 5px } a.banner-button:hover { background: var(--btn-bg); } [data-theme=dark] .page-top-card { opacity: .7 } @media screen and (max-width:900px) { .page-top-card { padding: 10px 1rem; height: 12rem; margin: 0 5px } .content-bottom { width: calc(100% - 2rem) } a.banner-button span { display: none } a.banner-button { width: 50px; height: 35px; display: flex; align-items: center; justify-content: center } a.banner-button i { margin: 0 } } </style>
文章目录 新建[BlogRoot]/source/css/aside_toc.css
方案一,透明目录(Heo化太多了,自己直接做透明了,最好手动调一下颜色让文字鲜艳些以适配自己的背景)
@media screen and (min-width : 900px ) { #aside-content .card-widget #card-toc { background-color : transparent !important ; box-shadow : none !important ; border : none; } #aside-content #card-toc .item-headline { opacity : 0 ; } } #aside-content #card-toc .toc-content > * > .toc-item > .toc-child { border-left : none !important ; } #aside-content #card-toc .toc-content .toc-link .active { display : flex; transform : scale (1.2 ); background : none; color : var (--zhsher-lighttext); font-weight : bold; } #aside-content #card-toc .toc-content .toc-link .active :before { content : " " !important ; margin-top : 0.8rem !important ; margin-right : 0.5rem ; width : 0.8rem !important ; height : 0.2rem !important ; border-radius : 0.1rem !important ; background : var (--zhsher-lighttext); } #aside-content #card-toc .toc-content ::-webkit-scrollbar-thumb, #aside-content #card-toc .toc-content::-webkit-scrollbar-corner { background-color : transparent; }
方案二,heo哥目录(取自heo哥F12)
#aside-content #card-toc .toc-content .toc-link .active { line-height : 1.2 ; border-radius : 12px ; border-left-color : var (--heo-hovertext); background-color : var (--heo-card-bg); color : var (--heo-lighttext); font-weight : bold; font-size : 20px ; } [data-theme=dark] .toc .toc-item .active .toc-link .toc-text { color : var (--heo-white); } #aside-content #card-toc .toc-content .toc-item .active .toc-link { opacity : 1 ; border-radius : 8px ; } #aside-content #card-toc .toc-content .toc-link { line-height : 1.2 ; padding : 8px ; border-left : 0px solid transparent; border-radius : 12px ; color : var (--heo-secondtext); cursor : default; } #aside-content #card-toc .toc-content .toc-link :not (.active ) span { opacity : 0.6 ; cursor : pointer; filter : blur (1px ); transition : 0.3s ; } #aside-content #card-toc :hover .toc-content .toc-link :not (.active ) span { filter : blur (0px ); opacity : 1 ; } #aside-content #card-toc .toc-content .toc-link :not (.active ) span :hover { color : var (--heo-lighttext); } #card-toc { padding : 0.5rem 0.5rem !important ; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/aside_toc.css">
小张比较喜欢简化风格,所以隐藏了除目录外的其它卡片,toc.style_simple: true
Github 贡献日历 原文地址:hexo-githubcalendar | 小冰博客
安装
npm i hexo-githubcalendar --save
修改配置文件 _config.yml,在最后新增
githubcalendar: enable: true priority: 3 enable_page: / user: GC-ZF layout: type: id name: recent-posts index: 0 githubcalendar_html: '<div class="recent-post-item" style="width:100%;height:auto;padding:10px;"><div id="github_loading" style="width:10%;height:100%;margin:0 auto;display: block"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50" xml:space="preserve"><path fill="#d0d0d0" d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" transform="rotate(275.098 25 25)"><animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="0.6s" repeatCount="indefinite"></animateTransform></path></svg></div><div id="github_container"></div></div>' pc_minheight: 280px mobile_minheight: 0px color: "['#ebedf0', '#fdcdec', '#fc9bd9', '#fa6ac5', '#f838b2', '#f5089f', '#c4067e', '#92055e', '#540336', '#48022f', '#30021f']" api: https://gitcalendar.zfe.space/api calendar_js: https://jsd.onmicrosoft.cn/gh/Zfour/hexo-github-calendar@1.21/hexo_githubcalendar.min.js plus_style: ""
在其它页面中挂载,只需在对应md文件中插入
<div name ="我是墙" id ="history_calendar" > <div name ="我是画框" > <div name ="我是纸" > </div > </div > </div >
文章双栏布局 原文地址:
安装
npm i hexo-butterfly-article-double-row --save
修改配置文件 _config.yml,在最后新增
butterfly_article_double_row: enable: true
如果每页文章太少,可以调整index_generator属性
index_generator: path: '' per_page: 12 order_by: -date
但是文章最后一页页码按钮会错位,所以不用插件直接用小冰老师的css文件做一个微调
新建[BlogRoot]/source/css/double row.css
#recent-posts { margin-top : -1rem ; align-content : flex-start; display : flex; flex-wrap : wrap; justify-content : space-between; } #recent-posts > .recent-post-item { margin-top : 1rem ; display : inline-block; height : auto; width : 49% ; } #recent-posts > .recent-post-item .post_cover { width : 100% ; height : 200px ; } #recent-posts > .recent-post-item .post_cover img .post_bg { width : 100% ; height : 100% ; } #recent-posts > .recent-post-item > .recent-post-info > .content { display : none; } #recent-posts > .recent-post-item { -webkit-flex-direction : column; -ms-flex-direction : column; flex-direction : column; } #recent-posts > .recent-post-item .left_radius { border-radius : 8px 8px 0 0 ; } #recent-posts > .recent-post-item .right_radius { border-radius : 8px 8px 0 0 ; } .recent-post-item { height : auto !important ; } .recent-post-info { padding : 0 40px ; margin-top : 1em ; width : 100% !important ; } #recent-posts > .recent-post-item > .recent-post-info > .article-title { -webkit-line-clamp: 1 ; margin-top : 0.3rem ; margin-bottom : 0.3rem ; color : var (--text-highlight-color); font-size : 1.2em ; line-height : 1.4 ; } #recent-posts > .recent-post-item > .recent-post-info > .article-meta-wrap { margin-bottom : 1rem ; } @media screen and (max-width : 768px ) { #recent-posts > .recent-post-item { width : 100% ; } } nav #pagination { width : 100% ; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/double row.css">
时钟(已移除) 原文地址:
安装
npm install hexo-butterfly-clock-anzhiyu --save
修改配置文件 _config.yml,在最后新增
electric_clock: enable: true priority: 5 enable_page: all exclude: layout: type: class name: sticky_layout index: 0 loading: https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu@1.1.6/lib/loading.gif clock_css: https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu@1.1.6/lib/clock.min.css clock_js: https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu@1.1.6/lib/clock.min.js ip_api: https://widget.qweather.net/simple/static/js/he-simple-common.js?v=2.0 qweather_key: gaud_map_key: default_rectangle: true rectangle: 112.6534116 ,27.96920845
hexo-magnet 原文地址:hexo-magnet 插件 1.0 | 小冰博客
功能:
自定义 tags 或 categories 的排列和展示 自定义 tags 或 categories 的展示图标,名称 自定义排列的行数,默认 2 行 安装
修改配置文件 _config.yml,在最后新增
type:categories/tags name:分类原名 display_name:替换名称 icon:图标 magnet: enable: true priority: 8 enable_page: / type: categories devide: 2 display: - name: 小张列传 display_name: 小张列传 icon: 📚 - name: 服务器 display_name: 瞎折腾服务器 icon: 👩💻 color_setting: text_color: black text_hover_color: white background_color: "#f2f2f2" background_hover_color: "#b30070" layout: type: id name: recent-posts index: 0 temple_html: '<div class="recent-post-item" style="width:100%;height: auto"><div id="catalog_magnet">${temple_html_item}</div></div>' plus_style: ""
文章轮播置顶 原文地址: hexo-butterfly-swiper | Akilarの糖果屋
安装
npm install hexo-butterfly-swiper --save
修改配置文件 _config.yml,在最下面添加
swiper: enable: true priority: 5 enable_page: all timemode: date layout: type: id name: recent-posts index: 0 default_descr: 再怎么看我也不知道怎么描述它的啦! swiper_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.css swiper_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.js custom_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiperstyle.css custom_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper_init.js
在文章的front_matter中添加swiper_index配置项
Wowjs 原文地址:Add Blog Animation – Wowjs | Akilarの糖果屋
安装
npm install hexo-butterfly-wowjs --save
修改配置文件 _config.yml,在最下面添加
wowjs: enable: true priority: 10 mobile: false animateitem: - class: recent-post-item style: animate__zoomIn duration: 1. 5s delay: 200ms offset: 30 iteration: 1 - class: card-widget style: animate__zoomIn animate_css: https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/animate.min.css wow_js: https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow.min.js wow_init_js: https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow_init.js
文章密码 文档地址:hexo-blog-encrypt Github
安装
npm install --save hexo-blog-encrypt
使用时修改文章的front_matter,password必选,其它选填。也可以将整个分类加密,具体参考文档
--- password: mikemessi abstract: 有东西被加密了, 请输入密码查看. message: 您好, 这里需要密码. wrong_pass_message: 抱歉, 这个密码看着不太对, 请再试试. wrong_hash_message: 抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容. ---
视频 通常用<iframe height=500 width=500 src='xxxx' frameborder=0 'allowfullscreen'></iframe>标签插入视频,但本地markdown软件打开文件总是自动播放,所以借助插件会方便一些
文档地址:hexo-tag-dplayer | Github
基于DIYgod/DPlayer 修改,hexo-tag-dplayer 具体参数可以参考它
安装
npm install --save hexo-tag-dplayer
使用
{% dplayer "url=xxx" "autoplay=false" %}
选项 默认值 描述 选项 默认值 描述 url 必须值 视频地址 autoplay true 自动播放,移动端浏览器暂时不支持 pic 视频封面 loop false 视频循环播放 screenshot false 视频截图 hotkey true 开启热键,支持快进、快退、音量控制、播放暂停 mutex true 阻止多个播放器同时播放 width,height 宽高,例”width=854px” “height=480px” theme #ad7a86 播放器风格色彩设置 preload auto 视频文件预载入模式,可选项: none, metadata, auto lang zh-cn ‘en’, ‘zh-cn’, ‘zh-tw’ logo url,在左上角展示一个 logo volume 0.7 播放器音量
原文地址:[【源码开放】Hexo+Github 博客butterfly 和 matery 主题 搭建完全教程【整理】 | 超逸の博客](https://yangchaoyi.vip/posts/520520/#页面底部 footer 跳动的心)
编辑 [BlogRoot]/themes/Butterfly/layout/includes/footer.pug
-©${theme.since} - ${nowYear} By ${config.author} +©${theme.footer.owner.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} //最底部添加 +<head><link rel="stylesheet" href="https://jsd.onmicrosoft.cn/gh/HCLonely/images@master/others/heartbeat.min.css"></head>
朋友圈 文档地址:hexo-filter-fcircle
本博客目前采用GitHub+Leancloud+yyyz前端方案 部署,朋友圈项目迭代特别快,不再详细记录,根据文档最新教程部署即可
鼠标右击美化 原文地址:
修改PUG 新建 [BlogRoot]/themes/butterfly/layout/includes/rightmenu.pug
#rightMenu .rightMenu-group .rightMenu-small a .rightMenu-item (href="javascript:window.history.back ();") i .fa .fa-arrow-left a .rightMenu-item (href="javascript:window.history.forward ();") i .fa .fa-arrow-right a .rightMenu-item (href="javascript:window.location.reload ();") i .fa .fa-refresh a .rightMenu-item (href="javascript:rmf.scrollToTop ();") i .fa .fa-arrow-up .rightMenu-group .rightMenu-line .hide #menu-text a .rightMenu-item (href="javascript:rmf.copySelect ();") i .fa .fa-copy span ='复制' a .rightMenu-item (href="javascript:window.open (\"https://www.baidu.com/s?wd=\"+window.getSelection().toString());window.location.reload();" ) i.fa-solid.fa-magnifying-glass span='百度搜索' .rightMenu-group.rightMenu-line.hide#menu-too a.rightMenu-item (href="javascript:window.open(window.getSelection().toString());window.location.reload();" ) i.fa.fa-link span='转到链接' .rightMenu-group.rightMenu-line.hide#menu-paste a.rightMenu-item (href='javascript:rmf.paste()' ) i.fa.fa-copy span='粘贴' .rightMenu-group.rightMenu-line.hide#menu-post a.rightMenu-item (href="#post-comment" ) i.fas.fa-comment span='空降评论' a.rightMenu-item (href="javascript:rmf.copyWordsLink()" ) i.fa.fa-link span='复制本文地址' .rightMenu-group.rightMenu-line.hide#menu-to a.rightMenu-item (href="javascript:rmf.openWithNewTab()" ) i.fa.fa-window-restore span='新窗口打开' a.rightMenu-item#menu-too (href="javascript:rmf.open()" ) i.fa.fa-link span='转到链接' a.rightMenu-item (href="javascript:rmf.copyLink()" ) i.fa.fa-copy span='复制链接' .rightMenu-group.rightMenu-line.hide#menu-img a.rightMenu-item (href="./#post-comment" ) i.fa.fa-download span='保存图片' a.rightMenu-item (href="javascript:rmf.openWithNewTab()" ) i.fa.fa-window-restore span='在新窗口打开' a.rightMenu-item (href="javascript:rmf.click()" ) i.fa.fa-arrows-alt span='全屏显示' a.rightMenu-item (href="javascript:rmf.copyLink()" ) i.fa.fa-copy span='复制图片链接' .rightMenu-group.rightMenu-line //a.rightMenu-item (href="javascript:toRandomPost()" ) // i.fa.fa-paper-plane // span='随便逛逛' a.rightMenu-item (href="javascript:rmf.switchDarkMode();" ) i.fa.fa-moon span='昼夜切换' a.rightMenu-item (href="javascript:rmf.translate();" ) i.fas.fa-language span='繁简转换' if is_home () == false a.rightMenu-item (href="javascript:rmf.switchReadMode();" ) i.fa.fa-book span='阅读模式' a.rightMenu-item (href="javascript:window.location.href=\"/about/\";" ) i.fa.fa-info-circle span='关于小张'
[BlogRoot]/themes/butterfly/layout/includes/layout.pug中引入(注意缩进,去掉+)
include ./rightside.pug include ./additional-js.pug !=partial('includes/third-party/search/index', {}, {cache: true}) + !=partial('includes/rightmenu',{}, {cache:true})
CSS 新建 [BlogRoot]/themes/butterfly/source/css/rightmenu/rightmenu.css
[data-theme='light' ] #rightMenu { display : none; position : fixed; width : 160px ; height : fit-content; top : 10% ; left : 10% ; background-color : var (--card-bg); border : 1px solid rgb (210 ,210 ,210 );; border-radius : 8px ; z-index : 100 ; box-shadow : 3px 3px 5px #88888894 ; background-color : var (--zhshier-white-acrylic1); backdrop-filter : blur (30px ); } [data-theme='dark' ] #rightMenu { display : none; position : fixed; width : 160px ; height : fit-content; top : 10% ; left : 10% ; background-color : var (--card-bg); border : 1px solid rgb (210 ,210 ,210 );; border-radius : 8px ; z-index : 100 ; box-shadow : 3px 3px 5px #88888894 ; background-color : var (--zhshier-black-acrylic1); backdrop-filter : blur (30px ); } #rightMenu .rightMenu-group { padding : 7px 6px ; } #rightMenu .rightMenu-group :not (:nth-last-child (1 )){ border-bottom : 1px solid rgb (180 ,180 ,180 ); } #rightMenu .rightMenu-group .rightMenu-small { display : flex; justify-content : space-between; } #rightMenu .rightMenu-group .rightMenu-item { height : 30px ; line-height : 30px ; border-radius : 8px ; transition : 0.3s ; color : var (--font-color); } #rightMenu .rightMenu-group .rightMenu-line .rightMenu-item { display : flex; height : 40px ; line-height : 40px ; padding : 0 4px ; } #rightMenu .rightMenu-group .rightMenu-item :hover { background-color : var (--text-bg-hover); box-shadow : 0px 0px 5px var (--zhshier-border); } #rightMenu .rightMenu-group .rightMenu-item i { display : inline-block; text-align : center; line-height : 30px ; width : 30px ; height : 30px ; padding : 0 5px ; } #rightMenu .rightMenu-group .rightMenu-item span { line-height : 30px ; } #rightMenu :hover { border : 1px solid var (--zhshier-blue); } #rightMenu .rightMenu-group .rightMenu-line .rightMenu-item *{ height : 40px ; line-height : 40px ; } .rightMenu-group .hide { display : none; } .rightMenu-item :hover { color :white!important ; background-color :var (--zhshier-blue)!important ; } :root { --zhshier-border :#c9c9c9 ; --zhshier-blue :#6cf ; --zhshier-black-acrylic1 : #0008 ; --zhshier-white-acrylic1 :#fffd ; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/rightmenu/rightmenu.css">
iconfont图标 因为少部分图标使用iconfont,你需要自己添加,下载LYX的iconfont图标包 ,然后解压把里面的东西扔到 [BlogRoot]/themes/butterfly/source/css/rightmenu/里面即可(图片源自阿里图标,也可以自己直接用主题自带的矢量图标)
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/iconfont.css">
JS 新建 [BlogRoot]/themes/butterfly/source/js/rightmenu.js
console .log ( "Codes uses GPL Licence" ) function insertAtCursor (myField, myValue ) { if (document .selection ) { myField.focus (); sel = document .selection .createRange (); sel.text = myValue; sel.select (); } else if (myField.selectionStart || myField.selectionStart == '0' ) { var startPos = myField.selectionStart ; var endPos = myField.selectionEnd ; var restoreTop = myField.scrollTop ; myField.value = myField.value .substring (0 , startPos) + myValue + myField.value .substring (endPos, myField.value .length ); if (restoreTop > 0 ) { myField.scrollTop = restoreTop; } myField.focus (); myField.selectionStart = startPos + myValue.length ; myField.selectionEnd = startPos + myValue.length ; } else { myField.value += myValue; myField.focus (); } } let rmf = {};rmf.showRightMenu = function (isTrue, x = 0 , y = 0 ) { let $rightMenu = $('#rightMenu' ); $rightMenu.css ('top' , x + 'px' ).css ('left' , y + 'px' ); if (isTrue) { $rightMenu.show (); } else { $rightMenu.hide (); } } rmf.switchDarkMode = function ( ) { const nowMode = document .documentElement .getAttribute ('data-theme' ) === 'dark' ? 'dark' : 'light' if (nowMode === 'light' ) { activateDarkMode () saveToLocal.set ('theme' , 'dark' , 2 ) GLOBAL_CONFIG .Snackbar !== undefined && btf.snackbarShow (GLOBAL_CONFIG .Snackbar .day_to_night ) } else { activateLightMode () saveToLocal.set ('theme' , 'light' , 2 ) GLOBAL_CONFIG .Snackbar !== undefined && btf.snackbarShow (GLOBAL_CONFIG .Snackbar .night_to_day ) } typeof utterancesTheme === 'function' && utterancesTheme () typeof FB === 'object' && window .loadFBComment () window .DISQUS && document .getElementById ('disqus_thread' ).children .length && setTimeout (() => window .disqusReset (), 200 ) }; rmf.copyWordsLink = function ( ) { let url = window .location .href let txa = document .createElement ("textarea" ); txa.value = url; document .body .appendChild (txa) txa.select (); document .execCommand ("Copy" ); document .body .removeChild (txa); Swal .fire ("复制成功!" ); } rmf.switchReadMode = function ( ) { const $body = document .body $body.classList .add ('read-mode' ) const newEle = document .createElement ('button' ) newEle.type = 'button' newEle.className = 'fas fa-sign-out-alt exit-readmode' $body.appendChild (newEle) function clickFn ( ) { $body.classList .remove ('read-mode' ) newEle.remove () newEle.removeEventListener ('click' , clickFn) } newEle.addEventListener ('click' , clickFn) } rmf.copySelect = function ( ) { document .execCommand ('Copy' , false , null ); } rmf.scrollToTop = function ( ) { btf.scrollToDest (0 , 500 ); } rmf.translate = function ( ) { document .getElementById ("translateLink" ).click (); } document .onkeydown = function (event ) { event = (event || window .event ); if (event.keyCode == 17 ) { console .log ("你知道的太多了" ); return ; } } function popupMenu ( ) { window .oncontextmenu = function (event ) { if (event.ctrlKey )return true ; console .log (event.keyCode ) $('.rightMenu-group.hide' ).hide (); if (document .getSelection ().toString ()) { $('#menu-text' ).show (); } if (document .getElementById ('post' )) { $('#menu-post' ).show (); } else { if (document .getElementById ('page' )) { $('#menu-post' ).show (); } } var el = window .document .body ; el = event.target ; var a=/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\*\+,;=.]+$/ if (a.test (window .getSelection ().toString ())){ $('#menu-too' ).show () } if (el.tagName == 'A' ) { $('#menu-to' ).show () rmf.open = function ( ) { location.href = el.href } rmf.openWithNewTab = function ( ) { window .open (el.href ); } rmf.copyLink = function ( ) { let url = el.href let txa = document .createElement ("textarea" ); txa.value = url; document .body .appendChild (txa) txa.select (); document .execCommand ("Copy" ); document .body .removeChild (txa); } } if (el.tagName == 'IMG' ) { $('#menu-img' ).show () rmf.openWithNewTab = function ( ) { window .open (el.src ); } rmf.click = function ( ) { el.click () } rmf.copyLink = function ( ) { let url = el.src let txa = document .createElement ("textarea" ); txa.value = url; document .body .appendChild (txa) txa.select (); document .execCommand ("Copy" ); document .body .removeChild (txa); } } else if (el.tagName == "TEXTAREA" || el.tagName == "INPUT" ) { $('#menu-paste' ).show (); rmf.paste = function ( ) { navigator.permissions .query ({ name : 'clipboard-read' }) .then (result => { if (result.state == 'granted' || result.state == 'prompt' ) { navigator.clipboard .readText ().then (text => { console .log (text) insertAtCursor (el, text) }) } else { alert ('请允许读取剪贴板!' ) } }) } } let pageX = event.clientX + 10 ; let pageY = event.clientY ; let rmWidth = $('#rightMenu' ).width (); let rmHeight = $('#rightMenu' ).height (); if (pageX + rmWidth > window .innerWidth ) { pageX -= rmWidth + 10 ; } if (pageY + rmHeight > window .innerHeight ) { pageY -= pageY + rmHeight - window .innerHeight ; } rmf.showRightMenu (true , pageY, pageX); return false ; }; window .addEventListener ('click' , function ( ) { rmf.showRightMenu (false ); }); } if (!(navigator.userAgent .match (/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i ))) { popupMenu () } const box = document .documentElement function addLongtabListener (target, callback ) { let timer = 0 target.ontouchstart = () => { timer = 0 timer = setTimeout (() => { callback (); timer = 0 }, 380 ) } target.ontouchmove = () => { clearTimeout (timer) timer = 0 } target.ontouchend = () => { if (timer) { clearTimeout (timer) } } } addLongtabListener (box, popupMenu)
因为这个js依赖于jquery,所以还需要引入jquery,修改主题配置文件_config.butterfly.yml,引入js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> bottom: # - <script src="xxxx"></script> + - <script defer type="text/javascript" src="https://jsd.onmicrosoft.cn/npm/jquery@latest/dist/jquery.min.js"></script> + - <script defer type="text/javascript" src="/js/rightmenu.js"></script>
悬浮伸缩侧边栏 原文地址:给网站增加悬浮伸缩侧边栏 | 轻笑Chuckle
修改[BlogRoot]/themes/butterfly/layout/includes/layout.pug,注意修改歌单id
include ./rightside.pug !=partial('includes/third-party/search/index', {}, {cache: true}) !=partial('includes/dorakika/rightmenu',{}, {cache:true}) include ./additional-js.pug //- 上面的是本来就有的,对齐上面的缩进,加上下面的内容 // 侧边悬浮栏 .contact-info .option i.fas.fa-rocket .bloktop .text .strip <div class="aside_notice">鉴于评论非即时聊天、问题描述不清晰,可以加我并附上你的问题截图。🐧:1310446718,VX:GC_XiaoZhang(无偿,不要怕社恐小张也紧张!也不需要客气就当好朋友聊天就可以啦!)<br>糖果屋交流群:589330978<br>小N姐姐公益群:641126318</div> .option i.fas.fa-cube .blok .text .strip <div class="post-reward"><div class="reward-button"><i class="fa-solid fa-bolt"></i></div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/Hexo_img/config/wechat.png" target="_blank"><img class="post-qr-code-img entered loaded" src="/Hexo_img/config/wechat.png" alt="微信"></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="/Hexo_img/config/alipay.jpg" target="_blank"><img class="post-qr-code-img entered loaded" src="/Hexo_img/config/alipay.jpg" alt="支付宝"></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div> .option i.fas.fa-music .blokbottom .text.aplayertext .strip .aplayer.no-destroy(mutex='true', listfolded='true', data-id='7041302176', data-preload="none" , data-server='netease', data-volume='0.25', data-order='random', data-type='playlist', data-fixed='true', data-autoplay='false')
新建[BlogRoot]/source/css/asidefloat.css
.contact-info { position : fixed; top : 22% ; z-index : 200 ; left : -51px ; transition : 0.4s ; } .contact-info :hover { left : 0px ; } .contact-info .option { cursor : pointer; position : relative; } .contact-info .option i { display : block; width : 50px ; text-align : center; height : 60px ; line-height : 60px ; background : rgb (255 , 255 , 255 ); color : #b9b9b9 ; font-size : 20px ; transition : 0.4s ; border-radius : 0 10px 10px 0 ; } .contact-info .option :hover i { color : #3498db ; } .contact-info .text { border-radius : 15px ; position : absolute; height : 68px ; width : 200px ; background : rgba (255 , 255 , 255 , .85 ); top : 0 ; z-index : -1 ; left : -136px ; color : rgb (0 , 0 , 0 ); line-height : 60px ; text-align : center; transition : 0.4s ; } .contact-info .aplayertext { transition : none !important ; } .contact-info .aplayer { position : absolute !important ; } .contact-info .aplayer .aplayer-fixed .aplayer-body { left : -60px ; position : absolute !important ; width : 370px !important ; transition : none !important ; border-radius : 10px !important ; } .contact-info .aplayer .aplayer-fixed { left : -300px !important ; } .contact-info .option :hover .aplayer .aplayer-fixed .aplayer-body , .contact-info .option :hover .aplayer .aplayer-fixed { left : 0px !important ; } .contact-info .option :hover .text { left : 60px ; } .contact-info .blok { position : absolute; height : 60px ; width : 100px ; top : 0 ; z-index : -1 ; left : 0px ; } .contact-info .bloktop { position : absolute; height : 75px ; width : 100px ; bottom : 0px ; z-index : -1 ; left : 0px ; } .contact-info .blokbottom { position : absolute; height : 75px ; width : 100px ; top : 0 ; z-index : -1 ; left : 0px ; } .contact-info .option :hover .blok , .contact-info .option :hover .bloktop , .contact-info .option :hover .blokbottom { left : 0px ; } .contact-info .option :hover .aplayertext { left : 60px !important ; width : 370px !important ; background : transparent !important ; } .contact-info .aplayer .aplayer-fixed .aplayer-miniswitcher { border-radius : 0 10px 10px 0 !important ; } .contact-info .aplayer .aplayer-fixed .aplayer-body { transition : 0.28s !important ; border-radius : 10px !important ; height : 60px ; } .contact-info .aplayer .aplayer-pic { height : 60px !important ; } .contact-info .aplayer .aplayer-info { height : 60px !important ; } .aplayer .aplayer-list .aplayer-list-hide { margin-bottom : 59px !important ; } .contact-info .aplayer .aplayer-fixed .aplayer-list { margin-bottom : 62px !important ; max-height : 240px !important ; } .contact-info .aplayer .aplayer-fixed .aplayer-info { transition : none !important ; } .aplayer .aplayer-narrow .aplayer-body , .aplayer .aplayer-narrow .aplayer-pic { border-radius : 10px 0 0 10px !important ; } .aplayer .aplayer-fixed { border-radius : 10px !important ; } .aplayer .aplayer-pic { border-radius : 0 0 0 10px !important ; } .aplayer .aplayer-fixed .aplayer-list { border-radius : 10px 10px 0 0 !important ; } [data-theme=dark] .contact-info .option i { background : rgb (22 , 22 , 22 ); color : #b9b9b9 ; } [data-theme=dark] .contact-info .text { background : rgba (23 , 23 , 23 , 0.85 ); color : rgba (255 , 255 , 255 , 0.92 ); } @media screen and (max-width : 1300px ) { .contact-info { display : none !important ; } } .aplayer { opacity : .93 !important ; } [data-theme=dark] .aplayer { background : rgb (22 , 22 , 22 ) !important ; color : rgb (255 , 255 , 255 ); } [data-theme=dark] .aplayer .aplayer-fixed .aplayer-body { background : rgb (22 , 22 , 22 ) !important ; color : rgb (255 , 255 , 255 ); } [data-theme=dark] .aplayer .aplayer-list ol li :hover { background : #3b3b3b ; } [data-theme=dark] .aplayer .aplayer-list ol li .aplayer-list-light { background : #686868 ; } [data-theme=dark] .aplayer .aplayer-info .aplayer-controller .aplayer-time { color : #d4d4d4 ; } [data-theme=dark] .aplayer .aplayer-list ol li .aplayer-list-index { color : #d4d4d4 ; } [data-theme=dark] .aplayer .aplayer-list ol li .aplayer-list-author { color : #d4d4d4 ; } [data-theme=dark] .aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon path { fill: #d4d4d4 ; } .contact-info .text .strip { border-radius : 5px ; position : absolute; height : 36px ; width : 5px ; background : rgba (20 , 163 , 230 , 0.8 ); top : 12px ; z-index : -1 ; right : 4px ; transition : 0.4s ; } .contact-info .aplayertext .strip { transition : none !important ; } .contact-info .option :hover .aplayertext .strip { background : transparent; } [data-theme=dark] .contact-info .aplayer .aplayer-miniswitcher { background : rgba (23 , 23 , 23 , 0.85 ); } .contact-info .aplayer .aplayer-miniswitcher .aplayer-icon path { fill: #3498db ; } [data-theme=dark] .contact-info .option :hover i { color : #3498db ; } .contact-info .option .text .post-reward .tip-button__text { margin : 25px !important ; } .contact-info .option .text .post-reward .reward-main .reward-all { border-radius : 12px !important ; } .contact-info .option .text .post-reward .reward-button .reward-main .reward-all { z-index : 999 !important ; } [data-theme="dark" ] .contact-info .option .text .post-reward .tip-button { border : solid 2px rgba (236 , 233 , 233 , 0.8 ); background : #043749d0 ; } .contact-info .option :first -child:hover .text { height : 100px ; width : 300px ; line-height : 20px ; overflow : hidden; } .contact-info .option :first -child:hover .text .strip { top : 33px ; } .contact-info .option .text .aside_notice { word-wrap :break-word; padding :20px ; display : none; } .contact-info .option :first -child:hover .text .aside_notice { color : #0A84FF ; display : block; animation : notice 5s linear 0s infinite normal forwards; } .contact-info .option .text .aside_notice :hover { animation-play-state : paused!important ; cursor : pointer; } @keyframes notice { 0% { transform : translateY (90px ); } 100% { transform : translateY (-100% ); } } .contact-info .option .text .post-reward .reward-button { display : inline-flex; width : 90% ; position : relative; left : -9.7px ; border-radius : 15px ; } .contact-info .option .text .post-reward { margin-top : 0px ; } .contact-info .option .text .post-reward .reward-main .reward-all { display : inline-flex; } .contact-info .option .text .post-reward .reward-main { left : -60px ; line-height : 30px ; } .contact-info .option .text .post-reward .reward-main .reward-all :after { left : 110px ; } .contact-info .option .text .post-reward .reward-button i { background : yellow; border-radius : 10px ; animation : Breath 1.2s linear 1s infinite; color : var (--btn-bg) !important ; position : relative; left : 46px ; } @keyframes Breath { 0% { transform : scale (0.8 ); } 50% { transform : scale (1 ); } 100% { transform : scale (0.8 ); } } .contact-info .option .text .post-reward :hover .reward-button { background : linear-gradient (to left, yellow 50% , var (--btn-bg) 50% ); background-size : 200% ; background-position -x: -100% ; transition : .5s ease-out; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/twikoo.css">
即刻短文 Memos 原文地址:基于Memos实现说说和清单功能 | Leonus
其它Memos教程:
Memos需要服务器部署,类似无服务器的项目:
说说功能 创建说说页面hexo new page zone,并粘贴以下代码
<style > /* 页面初始化 */ div#page { background: none; border: 0; padding: 0; } [data-theme=dark] #twikoo .tk-content, #twikoo .tk-content { padding: 0; background: transparent; } .talk_item, .tk-expand, .tk-comments-container>.tk-comment, .tk-submit:nth-child(1){ background: var(--card-bg); border: 1px solid #e0e3ed; box-shadow: 0 5px 10px rgb(189 189 189 / 10%); transition: all .3s ease-in-out; border-radius: 12px; } .talk_item:hover, .tk-comments-container>.tk-comment:hover, .tk-submit:nth-child(1):hover { border-color: #49b1f5; } .tk-submit { padding: 20px 10px 0; } .tk-comments-container>.tk-comment { padding: 15px; } /* 页面初始化结束 */ #talk{ margin-top: 1rem; } #talk .loading { display: flex; align-items: center; justify-content: center; flex-direction: column; } #talk .loading img { width: 200px; } .talk_item { display: flex; flex-direction: column; padding: 20px; margin-bottom: 15px; } .avatar { margin: 0 !important; width: 60px; height: 60px; border-radius: 10px; } .talk_bottom, .talk_meta { display: flex; align-items: center; width: 100%; line-height: 1.5; } .talk_bottom{ justify-content: space-between; } .info { display: flex; flex-direction: column; margin-left: 10px; } span.talk_nick { color: #6dbdc3; font-size: 1.2rem; } svg.is-badge.icon { width: 15px; margin-left: 5px; padding-top: 3px; } span.talk_date { opacity: .6; } .talk_content { line-height: 1.5; margin-top: 10px; } .zone_imgbox { display: flex; flex-wrap: wrap; --w: calc(25% - 8px); gap: 10px; margin-top: 5px; } .zone_imgbox a { display: block; border-radius: 12px; width: var(--w); aspect-ratio: 1/1; position: relative; } .zone_imgbox img { width: 100%; height: 100%; margin: 0 !important; object-fit: cover; } /* 底部 */ .talk_bottom { opacity: .9; } .talk_bottom .icon { color: var(--font-color); float: right; transition: all .3s; } .talk_bottom .icon:hover { color: #49b1f5; } span.talk_tag{ font-size: 14px; } .talk_content>a { margin: 0 3px; color: #ff7d73 !important; } .talk_content>a:hover{ text-decoration: none !important; color: #ff5143 !important } /* 提醒 */ .limit { transition: all .3s ease-in-out; color: rgba(76, 73, 72, 0.6); } [data-theme=dark] .limit { color: rgba(255, 255, 255, 0.5); } .limit { display: none; text-align: center; margin-top: 20px; color: var(--font-color); } @media screen and (max-width: 900px) { .zone_imgbox { --w: calc(33% - 5px); } #talk{ margin: 10px 3px 0 } #post-comment{ margin: 0 3px } } @media screen and (max-width: 768px) { .zone_imgbox { gap: 6px; } .zone_imgbox { --w: calc(50% - 3px); } span.talk_date { font-size: 14px; } } </style > <div id ="talk" > <div class ='loading' > <img src ="/img/loading.svg" alt ="加载中..." > </div > </div > <div class ="limit" > - 只展示最近30条说说 -</div > <script > pageTalk(); // 页面说说 function pageTalk() { fetch('https://你的memos地址/api/v1/memo?creatorId=1&tag=说说&limit=30').then(res => res.json()).then(data => { // 注意修改域名 let items = [], html = '', icon = '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" class ="is-badge icon" > <path d ="m512 268c0 17.9-4.3 34.5-12.9 49.7s-20.1 27.1-34.6 35.4c.4 2.7.6 6.9.6 12.6 0 27.1-9.1 50.1-27.1 69.1-18.1 19.1-39.9 28.6-65.4 28.6-11.4 0-22.3-2.1-32.6-6.3-8 16.4-19.5 29.6-34.6 39.7-15 10.2-31.5 15.2-49.4 15.2-18.3 0-34.9-4.9-49.7-14.9-14.9-9.9-26.3-23.2-34.3-40-10.3 4.2-21.1 6.3-32.6 6.3-25.5 0-47.4-9.5-65.7-28.6-18.3-19-27.4-42.1-27.4-69.1 0-3 .4-7.2 1.1-12.6-14.5-8.4-26-20.2-34.6-35.4-8.5-15.2-12.8-31.8-12.8-49.7 0-19 4.8-36.5 14.3-52.3s22.3-27.5 38.3-35.1c-4.2-11.4-6.3-22.9-6.3-34.3 0-27 9.1-50.1 27.4-69.1s40.2-28.6 65.7-28.6c11.4 0 22.3 2.1 32.6 6.3 8-16.4 19.5-29.6 34.6-39.7 15-10.1 31.5-15.2 49.4-15.2s34.4 5.1 49.4 15.1c15 10.1 26.6 23.3 34.6 39.7 10.3-4.2 21.1-6.3 32.6-6.3 25.5 0 47.3 9.5 65.4 28.6s27.1 42.1 27.1 69.1c0 12.6-1.9 24-5.7 34.3 16 7.6 28.8 19.3 38.3 35.1 9.5 15.9 14.3 33.4 14.3 52.4zm-266.9 77.1 105.7-158.3c2.7-4.2 3.5-8.8 2.6-13.7-1-4.9-3.5-8.8-7.7-11.4-4.2-2.7-8.8-3.6-13.7-2.9-5 .8-9 3.2-12 7.4l-93.1 140-42.9-42.8c-3.8-3.8-8.2-5.6-13.1-5.4-5 .2-9.3 2-13.1 5.4-3.4 3.4-5.1 7.7-5.1 12.9 0 5.1 1.7 9.4 5.1 12.9l58.9 58.9 2.9 2.3c3.4 2.3 6.9 3.4 10.3 3.4 6.7-.1 11.8-2.9 15.2-8.7z" fill ="#1da1f2" > </path > </svg > '; data.data.forEach(item => { items.push(Format(item)) }); if (items.length == 30) document.querySelector('.limit').style.display = 'block'; items.forEach(item => { html += `<div class ="talk_item" > <div class ="talk_meta" > <img class ="no-lightbox avatar" src="https://q1.qlogo.cn/g?b=qq&nk=553344777&s=5" > <div class ="info" > <span class ="talk_nick" > Leonus${icon}</span > <span class ="talk_date" > ${item.date}</span > </div > </div > <div class ="talk_content" > ${item.content}</div > <div class ="talk_bottom" > <div > <span class ="talk_tag" > # ${item.tag}</span > </div > <a href ="javascript:;" onclick ="goComment('${item.text}')" > <span class ="icon" > <i class ="fa-solid fa-message fa-fw" > </i > </span > </a > </div > </div > ` // 注意修改头像链接和名称 }) document.getElementById('talk').innerHTML = html }) } // 页面评论 function goComment(e) { var n = document.querySelector(".el-textarea__inner") n.value = `> ${e}\n\n`; n.focus(); btf.snackbarShow("无需删除空行,直接输入评论即可", !1, 2e3); } // 页面内容格式化 function Format(item) { let date = getTime(new Date(item.createdTs * 1000).toString()), content = item.content, tag = item.content.match(/\{(.*?)\})/g), imgls = content.match(/!\[.*\]\(.*?\)/g), // 2023-02-06更新 text = '' text = content.replace(/#(.*?)\s/g, '').replace(/\!\[(.*?)\]\((.*?)\)/g, '').replace(/\{(.*?)\}/g, '') content = text.replace(/\[(.*?)\]\((.*?)\)/g, `<a href ="$2" > @$1</a > `); if (imgls) { content += `<div class ="zone_imgbox" > ` imgls.map(item => { return item.replace(/!\[.*\]\((.*?)\)/, '$1') }).forEach(e => content += `<a href="${e}" data-fancybox="gallery" class ="fancybox" data-thumb="${e}" > <img src ="${e}" > </a > ` // 2023-02-06更新 ) content += '</div > ' } return { content: content, tag: tag ? tag[0].replace(/\{(.*?)\}/,'$1') : '无标签', date: date, text: text.replace(/\[(.*?)\]\((.*?)\)/g, '[链接]' + `${imgls?'[图片]':''}`) } } // 页面时间格式化 function getTime(time) { let d = new Date(time), ls = [d.getFullYear(), d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()]; for (let i = 0; i < ls.length; i++) { ls[i] = ls[i] <= 9 ? '0' + ls[i] : ls[i] + '' } if (new Date().getFullYear() == ls[0]) return ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4] else return ls[0] + '年' + ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4] } </script >
使用格式,其中**#说说固定,用于获取Memos内所有的带 #说说**标签的内容(如果图片加载失败,配置主题文件lazyload.field:post)
#说说 {说说标签} 我是内容 [我是链接](链接地址) 
首页轮播 修改[BlogRoot]/themes/butterfly/layout/includes/layout.pug
include ./header/index.pug ...上面原本的内容... if (is_home()) #main_top #bber-talk.wow.animate__flipInX(onclick=`pjax.loadUrl("/zone/")`) svg.icon(t='1660960757124', viewBox='0 0 1024 1024', version='1.1', xmlns='http://www.w3.org/2000/svg', p-id='3946', width='200', height='200') path(d='M526.432 924.064c-20.96 0-44.16-12.576-68.96-37.344L274.752 704H192c-52.928 0-96-43.072-96-96V416c0-52.928 43.072-96 96-96h82.752l182.624-182.624c24.576-24.576 47.744-37.024 68.864-37.024C549.184 100.352 576 116 576 160v704c0 44.352-26.72 60.064-49.568 60.064zM192 384c-17.632 0-32 14.368-32 32v192c0 17.664 14.368 32 32 32h96c8.48 0 16.64 3.36 22.624 9.376l192.064 192.096c3.392 3.36 6.496 6.208 9.312 8.576V174.016a145.824 145.824 0 0 0-9.376 8.608l-192 192C304.64 380.64 296.48 384 288 384h-96zM687.584 730.368a31.898 31.898 0 0 1-18.656-6.016c-14.336-10.304-17.632-30.304-7.328-44.672l12.672-17.344C707.392 617.44 736 578.624 736 512c0-69.024-25.344-102.528-57.44-144.928-5.664-7.456-11.328-15.008-16.928-22.784-10.304-14.336-7.04-34.336 7.328-44.672 14.368-10.368 34.336-7.04 44.672 7.328 5.248 7.328 10.656 14.464 15.968 21.504C764.224 374.208 800 421.504 800 512c0 87.648-39.392 141.12-74.144 188.32l-12.224 16.736c-6.272 8.704-16.064 13.312-26.048 13.312z', p-id='3947') path(d='M796.448 839.008a31.906 31.906 0 0 1-21.088-7.936c-13.28-11.648-14.624-31.872-2.976-45.152C836.608 712.672 896 628.864 896 512s-59.392-200.704-123.616-273.888c-11.648-13.312-10.304-33.504 2.976-45.184 13.216-11.648 33.44-10.336 45.152 2.944C889.472 274.56 960 373.6 960 512s-70.528 237.472-139.488 316.096c-6.368 7.232-15.2 10.912-24.064 10.912z', p-id='3948') ul.talk-list 说说加载中。。。 ...下面原本的内容... main#content-inner.layout(class=hideAside)
新建[BlogRoot]/source/css/memos.css
div #main_top { z-index : 1 ; max-width : 1200px ; margin : 20px auto -15px ; width : 100% ; padding : 0 15px ; } @media screen and (min-width : 2000px ) { div #main_top { max-width : 1500px ; } } #bber-talk { border-radius : 12px ; box-shadow : none; border : 1px solid #e0e3ed ; box-sizing : border-box; transition : all .3s ease-in-out; cursor : pointer; width : 100% ; min-height : 50px ; background : var (--card-bg); padding : .5rem 1rem ; display : flex; align-items : center; overflow : hidden; font-weight : 700 ; } #bber-talk :hover { border-color : #49b1f5 ; box-shadow : none; } #bber-talk ,#bber-talk a { color : var (--font-color); } #bber-talk svg.icon { width : 1em ; height : 1em ; vertical-align : -.15em ; fill: currentColor; overflow : hidden; font-size : 20px ; } #bber-talk .item i { margin-left : 5px ; } #bber-talk >i { font-size : 1.1rem ; } #bber-talk .talk-list { flex : 1 ; max-height : 32px ; font-size : 16px ; padding : 0 ; margin : 0 ; overflow : hidden; } #bber-talk .talk-list :hover { color : #49b1f5 !important ; transition : all .2s ease-in-out; } #bber-talk .talk-list li { list-style : none; width : 100% ; white-space : nowrap; text-overflow : ellipsis; overflow : hidden; margin-left : 10px ; } @media screen and (min-width : 768px ) { #bber-talk .talk-list { text-align : center; margin-right : 20px ; } }
新建[BlogRoot]/source/js/memos.js
function saveData (name, data ) { localStorage .setItem (name, JSON .stringify ({ 'time' : Date .now (), 'data' : data })) };function loadData (name, time ) { let d = JSON .parse (localStorage .getItem (name)); if (d) { let t = Date .now () - d.time if (-1 < t && t < (time * 60000 )) return d.data ; } return 0 ; }; let talkTimer = null ;function indexTalk ( ) { if (talkTimer) { clearInterval (talkTimer) talkTimer = null ; } if (!document .getElementById ('bber-talk' )) return function toText (ls ) { let text = [] ls.forEach (item => { text.push (item.content .replace (/#(.*?)\s/g , '' ).replace (/\{(.*?)\}/g , '' ).replace (/\!\[(.*?)\]\((.*?)\)/g , '<i class="fa-solid fa-image"></i>' ).replace (/(?<!!)\[(.*?)\]\((.*?)\)/g , '<i class="fa-solid fa-link"></i>' )) }); return text } function talk (ls ) { let html = '' ls.forEach ((item, i ) => { html += `<li class="item item-${i + 1 } ">${item} </li>` }); let box = document .querySelector ("#bber-talk .talk-list" ) box.innerHTML = html; talkTimer = setInterval (() => { box.appendChild (box.children [0 ]); }, 3000 ); } let d = loadData ('talk' , 10 ); if (d) talk (d); else { fetch ('https://你的memos地址/api/v1/memo?creatorId=1&tag=说说&limit=10' ).then (res => res.json ()).then (data => { data = toText (data.data ) talk (data); saveData ('talk' , data); }) } } indexTalk ();
修改主题配置文件_config.butterfly.yml,引入css、js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/memos.css"> bottom: # - <script src="xxxx"></script> + - <script async src="/js/memos.js"></script>
清单功能 创建说说页面hexo new page todo,并粘贴以下代码
<style > /* 页面初始化 */ div#page { background: none; border: 0; padding: 0; } [data-theme=dark] #twikoo .tk-content, #twikoo .tk-content { padding: 0; background: transparent; } .tk-comments-container>.tk-comment, .tk-submit:nth-child(1){ background: var(--card-bg); border: 1px rgba(188, 188, 188, 0.8) solid; box-shadow: 0 5px 10px rgb(189 189 189 / 10%); transition: all .3s ease-in-out; border-radius: 12px; } .tk-comments-container>.tk-comment:hover, .tk-submit:nth-child(1):hover { border-color: #6dc3fd; } .tk-submit { padding: 20px 10px 0; } .tk-comments-container>.tk-comment { padding: 15px; } /* 页面初始化结束 */ div#todolist { display: flex; flex-wrap: wrap; margin-top: 1rem; } .list_item { display: inline-block; width: calc(50% - .4rem); background: #ffe3dd; border-radius: 12px; padding: 10px 1rem 1.2rem; border: 2px dashed #f7a796; --todo-border: 1px solid #f7a796; margin-right: 1rem; margin-bottom: 1rem; } .list_item h3 { margin: 0; border-bottom: var(--todo-border); } .list_item ul { font-size: 17px; padding: 0 !important; margin: 0; } .list_item li{ margin: 0 !important; border-bottom: var(--todo-border); } .list_item li::marker { content: none; } li.achieve { opacity: .8; text-decoration: line-through; } @media screen and (max-width: 900px) { div#todolist { margin: 1rem 5px 0; } } @media screen and (max-width: 768px) { .list_item{ width: 100%; } } </style > <div id ="todolist" > </div > <script > // 瀑布流函数,不用管 function waterfall(t){function e(t,e){var n=window.getComputedStyle(e);return parseFloat(n["margin"+t])||0}function n(t){return t+"px"}function r(t){return parseFloat(t.style.left)}function o(t){return t.clientWidth}function l(t){return function(t){return parseFloat(t.style.top)}(t)+function(t){return t.clientHeight}(t)+e("Bottom",t)}function i(t){return r(t)+o(t)+e("Right",t)}function u(t){t=t.sort((function(t,e){return l(t)===l(e)?r(e)-r(t):l(e)-l(t)}))}function a(e){o(t)!=h&&(e.target.removeEventListener(e.type,arguments.callee),waterfall(t))}"string"==typeof t&&(t=document.querySelector(t));var s=[].map.call(t.children,(function(t){return t.style.position="absolute",t}));t.style.position="relative";var f=[];s.length&&(s[0].style.top="0px",s[0].style.left=n(e("Left",s[0])),f.push(s[0]));for(var p=1;p<s.length ;p++){var c=s[p-1 ],y=s[p];if (!(i (c)+o (y)<=o (t)))break ;y.style .top =c.style .top ,y.style .left =n (i (c)+e ("Left" ,y)),f.push (y)}for (;p<s.length ;p++){u (f);y=s[p];var d=f.pop ();y.style .top =n (l (d)+e ("Top" ,y)),y.style .left =n (r (d)),f.push (y)}u (f);var v=f[0 ];t.style .height =n (l (v));var h=o (t);window .addEventListener ?window .addEventListener ("resize" ,a):document .body .onresize =a} todolist ();function todolist ( ) { fetch ('https://你的memos地址/api/v1/memo?creatorId=1&tag=清单' ).then (res => res.json()).then(data => { // 注意替换链接 // 获取并处理数据 data = data.data let box = document.getElementById('todolist') data.forEach(item => { // 处理数据 let content = item.content, title = content.match(/(?<=#.* \[)(.*?)(?=\])/g); // 去掉多余内容,替换清单内容 content = content.replace(/#.* \s/g, '').replace(/(-\s\[\s\]\s)(.*)(?=\s* )/g, `<li><i style="margin-right: 5px;" class="fa-regular fa-circle"></i>$2</li>` ).replace(/(-\s\[x\]\s)(.*)(?=\s* )/g, `<li class="achieve"><i style="margin-right: 5px;" class="fa-regular fa-circle-check"></i>$2</li>` ); // 渲染数据 let div = document.createElement('div'); div.className = 'list_item'; div.innerHTML = `<h3>${title}</h3><ul>${content}</ul>`; box.appendChild(div); }); waterfall('#todolist'); }).catch() } </script>
使用
#清单 [计划] - [ ] 测试Memos - [x] 测试Memos
Heo同款loading动画 原文地址:安知鱼 - 生活明朗 万物可爱
修改[BlogRoot]/themes/butterfly/layout/includes/loading/fullpage-loading.pug
-#loading-box - .loading-left-bg - .loading-right-bg - .spinner-box - .configure-border-1 - .configure-core - .configure-border-2 - .configure-core - .loading-word= _p('loading') +#loading-box(onclick='document.getElementById("loading-box").classList.add("loaded")') + .loading-bg + div.loading-img + .loading-image-dot
修改[BlogRoot]/themes/butterfly/layout/includes/loading/index.pug
if theme.preloader.source === 1 include ./fullpage-loading.pug else if theme.preloader.source === 2 include ./pace.pug else include ./fullpage-loading.pug include ./pace.pug
新建source/css/progress_bar.css,也可以不做这一步下面配置文件pace_css_url这一项就要留空,,这一步是修改 pace 加载的胶囊 💊 样式用的
.pace { -webkit-pointer-events : none; pointer-events : none; -webkit-user-select: none; -moz-user-select: none; user-select: none; z-index : 2000 ; position : fixed; margin : auto; top : 10px ; left : 0 ; right : 0 ; height : 8px ; border-radius : 8px ; width : 4rem ; background : #eaecf2 ; border : 1px #e3e8f7 ; overflow : hidden; } .pace-inactive .pace-progress { opacity : 0 ; transition : 0.3s ease-in; } .pace .pace-progress { -webkit-box-sizing : border-box; -moz-box-sizing : border-box; -ms-box-sizing : border-box; -o-box-sizing : border-box; box-sizing : border-box; -webkit-transform : translate3d (0 , 0 , 0 ); -moz-transform : translate3d (0 , 0 , 0 ); -ms-transform : translate3d (0 , 0 , 0 ); -o-transform : translate3d (0 , 0 , 0 ); transform : translate3d (0 , 0 , 0 ); max-width : 200px ; position : absolute; z-index : 2000 ; display : block; top : 0 ; right : 100% ; height : 100% ; width : 100% ; background : linear-gradient (-45deg , #ee7752 , #e73c7e , #23a6d5 , #23d5ab ); animation : gradient 1.5s ease infinite; background-size : 200% ; } .pace .pace-inactive { opacity : 0 ; transition : 0.3s ; top : -8px ; } @keyframes gradient { 0% { background-position : 0% 50% ; } 50% { background-position : 100% 50% ; } 100% { background-position : 0% 50% ; } }
修改themes/butterfly/source/css/_layout/loading.styl,注意其中颜色代码--anzhiyu-card-bg等需自行替换为自己的色值。
if hexo-config ('preloader' ) .loading-bg display : flex; width : 100% ; height : 100% ; position : fixed; background : var (--anzhiyu-card-bg); z-index : 1001 ; opacity : 1 ; transition : .3s ; #loading-box .loading-img width : 100px ; height : 100px ; border-radius : 50% ; margin : auto; border : 4px solid #f0f0f2 ; animation-duration : .3s ; animation-name : loadingAction; animation-iteration-count : infinite; animation-direction : alternate; .loading-image-dot width : 30px ; height : 30px ; background : #6bdf8f ; position : absolute; border-radius : 50% ; border : 6px solid #fff ; top : 50% ; left : 50% ; transform : translate (18px , 24px ); &.loaded .loading-bg opacity : 0 ; z-index : -1000 ; @keyframes loadingAction 0% { opacity : 1 ; } 100% { opacity : .4 ; }
在合适的地方加上自定义 css, 其中 background 的 url 即为 loading 的图片地址。
.loading-img { background : url (https://q1.qlogo.cn/g?b=qq&nk=1310446718&s=5 ) no-repeat center center; background-size : cover; }
修改主题配置文件_config.butterfly.yml,source: 1为满屏加载无pace胶囊,source: 2为pace胶囊无满屏动画,source: 3是两者都启用。
preloader: enable: true source: 3 pace_css_url: /css/progress_bar.css
导航栏 原文地址:butterfly导航栏修改方案(自用方案) | 安知鱼
其它教程:关于Butterfly的导航栏的一些教程 | Ariasakaの小窝
新建[BlogRoot]/source/css/nav_menu.css
#nav a :hover { background : var (--zhsher-theme); transition : 0.3s ; } #nav-totop :hover .totopbtn i { opacity : 1 ; } #nav-totop #percent { font-size : 12px ; background : var (--zhsher-white); color : var (--zhsher-theme); width : 25px ; height : 25px ; border-radius : 35px ; display : flex; justify-content : center; align-items : center; transition : 0.3s ; } .nav-fixed #nav-totop #percent ,.page #nav-totop #percent { background : var (--font-color); color : var (--card-bg); font-size : 13px ; } #nav-totop { width : 35px ; } #page-header :not (.is-top-bar ) #percent { transition : 0.3s ; } #page-header :not (.is-top-bar ) #nav-totop { width : 0 ; opacity : 0 ; transition : width 0.3s , opacity 0.2s ; margin-left : 0 !important ; } #nav-totop #percent { font-weight : 700 ; } #nav-totop :hover #percent { opacity : 0 ; transform : scale (1.5 ); font-weight : 700 ; } #page-header #nav #nav-right div { margin-left : 0.5rem ; padding : 0 ; } #nav-totop { display : flex; align-items : center; justify-content : center; transition : 0.3s ; } .nav-button { cursor : pointer; } div #menus { display : flex; align-items : center; } #page-header #nav .nav-button a { height : 35px ; width : 35px ; display : flex; align-items : center; justify-content : center; } #nav .site-page { padding-bottom : 0px ; } #nav *::after { background-color : transparent !important ; } #nav .menus_items .menus_item .menus_item_child li a { padding : 2px 16px ; } #nav .menus_items .menus_item .menus_item_child li :hover a { color : white !important ; } #nav .menus_items .menus_item .menus_item_child li { margin : 6px ; border-radius : 5px ; transition : all 0.3s ; display : inline-block; margin : 0 3px ; } #nav .menus_items .menus_item .menus_item_child :before { top : -19px ; } #site-name ,.shuoshuo { white-space : nowrap; overflow : hidden; } #site-name { padding : 0 8px ; position : relative; display : flex; align-items : center; justify-content : center; transition : 0.3s ; } #blog-info #site-name i { opacity : 0 ; position : absolute; } #blog-info #site-name :hover .title { opacity : 0 ; } #blog-info #site-name :hover i { opacity : 1 ; transform : scale (1.01 ); color : white; } ul .menus_item_child { border-radius : 5px ; } #nav .menus_items { position : absolute; width : fit-content; left : 50% ; transform : translateX (-50% ); display : flex; flex-direction : row; justify-content : center; align-items : center; height : 60px ; } #nav .menus_items .menus_item :hover .menus_item_child { display : block; transform : translateX (-50% ); right : auto; left : auto !important ; padding : 6px 4px ; box-sizing : content-box; line-height : 35px ; } #nav .menus_items .menus_item :hover { padding : 0 5px 27px 5px !important ; margin-bottom : -14.5px !important ; } #nav .menus_items .menus_item .menus_item_child { top : 44px ; } @media screen and (min-width : 768px ) { .page .menus_item :hover > a .site-page { color : var (--zhsher-white) !important ; background : var (--zhsher-theme); transition : 0.3s ; box-shadow : var (--zhsher-shadow-main); } } .nav-fixed #nav { transform : translateY (58px ) !important ; } #nav { padding : 0 calc ((100% - 1420px ) / 2 ); backdrop-filter : saturate (180% ) blur (20px ); } #nav a { border-radius : 8px ; color : var (--font-color); } .page #nav a :hover { color : var (--zhsher-white) !important ; background : var (--zhsher-theme); transition : 0.3s ; box-shadow : var (--zhsher-shadow-main); } #menus > div .menus_items > div > a { letter-spacing : 0.3rem ; font-weight : 700 ; padding : 0em 0.3em 0em 0.5em ; height : 35px ; line-height : 35px ; } #nav .menus_items .menus_item { padding : 0 5px ; display : flex; flex-direction : column; margin : auto; align-items : center; } #nav div #toggle-menu { padding : 2px 0 4px 6px ; } #nav-totop .totopbtn i { position : absolute; display : flex; opacity : 0 ; } #page-name ::before { font-size : 18px ; position : absolute; width : 100% ; height : 100% ; border-radius : 8px ; color : white !important ; top : 0 ; left : 0 ; content : "回到顶部" ; background-color : var (--zhsher-theme); transition : all 0.3s ; -webkit-transition : all 0.3s ; -moz-transition : all 0.3s ; -ms-transition : all 0.3s ; -o-transition : all 0.3s ; opacity : 0 ; box-shadow : 0 0 3px var (--zhsher-theme); line-height : 45px ; } #page-name :hover :before { opacity : 1 ; } #name-container { transition : all 0.3s ; -webkit-transition : all 0.3s ; -moz-transition : all 0.3s ; -ms-transition : all 0.3s ; -o-transition : all 0.3s ; } #name-container :hover { transform : translateX (-50% ) scale (1.03 ); } #page-name { position : relative; padding : 10px 30px ; } center#name-container { position : absolute; width : 100% ; left : 50% ; transform : translateX (-50% ); font-family : "ZhuZiAYuanJWD" ; } .nav-fixed .nav-visible #name-container { transition : 0.3s ; transform : translate (-50% , 60px ); } .nav-fixed .nav-visible #menus .menus_items { transform : translate (-50% ); transition : 0.3s ; line-height : 60px ; } .nav-fixed #menus .menus_items { transform : translate (-50% , -60px ); transition : 0.3s ; } .nav-fixed #name-container { top : 15% ; transition : 0.3s ; } #name-container { bottom : 60px ; } .mask-name-container { max-width : 1200px ; width : 50% ; height : 100% ; position : absolute; overflow : hidden; left : 50% ; transform : translateX (-50% ); } @media screen and (max-width : 992px ) { .mask-name-container { width : 65% ; } } @media screen and (max-width : 768px ) { .mask-name-container { display : none; } } #sidebar #sidebar-menus .menus_items .site-page :hover { color : var (--zhsher-white); border-radius : var (--zhsher-border-radius); } #nav .menus_items .menus_item > a > i :last-child { display : none; } #nav #search-button { font-size : 1.3em ; } @media screen and (min-width : 900px ) { #nav .back-home-button :hover { box-shadow : var (--zhsher-shadow-main); } } .back-home-button :hover { background : var (--zhsher-theme); color : var (--zhsher-white) !important ; } .back-home-button { display : flex; width : 35px ; height : 35px ; padding : 0 !important ; align-items : center; justify-content : center; margin-right : 4px ; transition : 0.3s ; border-radius : 8px ; } .back-home-button :hover .back-menu-list-groups { display : flex; opacity : 1 ; transition : 0.3s ; top : 55px ; pointer-events : auto; left : 0 ; } .back-home-button .back-menu-list-groups { position : absolute; top : 65px ; left : 0 ; background : var (--zhsher-card-bg); border-radius : 12px ; border : var (--style-border); flex-direction : column; font-size : 12px ; color : var (--zhsher-secondtext); box-shadow : var (--zhsher-shadow-border); transition : 0s ; opacity : 0 ; pointer-events : none; } .back-home-button .back-menu-list-group { display : flex; flex-direction : column; } .back-home-button .back-menu-list-group .back-menu-list-title { margin : 8px 0 0 16px ; transition : 0.3s ; } .back-home-button .back-menu-list { display : flex; flex-direction : row; width : 332px ; flex-wrap : wrap; justify-content : space-between; } .back-home-button .back-menu-list ::before { position : absolute; top : -22px ; left : 0px ; width : 100% ; height : 25px ; content : "" ; } .back-home-button .back-menu-list-group :hover .back-menu-list-title { color : var (--zhsher-theme); } .back-home-button .back-menu-list-groups :hover { border : var (--style-border-hover); } .back-home-button .back-menu-list .back-menu-item { display : flex; align-items : center; margin : 4px 8px ; padding : 4px 8px !important ; transition : 0.3s ; border-radius : 8px ; width : 150px ; } .back-home-button .back-menu-list .back-menu-item .back-menu-item-text { font-size : var (--global-font-size); margin-left : 0.5rem ; color : var (--zhsher-fontcolor); white-space : nowrap; } #nav #blog-info { flex-wrap : nowrap; height : 60px ; display : flex; align-items : center; transition : 0.3s ; } .back-home-button .back-menu-list .back-menu-item .back-menu-item-icon { width : 24px ; height : 24px ; border-radius : 24px ; background : var (--zhsher-secondbg); } #page-header #nav .back-home-button { cursor : pointer; position : relative; } @media screen and (min-width : 1300px ) { #nav a :hover { transform : scale (1.03 ); } } .back-home-button .back-menu-list .back-menu-item :hover .back-menu-item-text { color : var (--zhsher-white); } .back-menu-item-icon .loading img { width : 25px ; } #page-header #nav #menus .nav-button .long a .totopbtn ,#page-header #nav #menus .nav-button .long ,#page-header #nav #menus .nav-button .long a .totopbtn span { width : 70px ; } #page-header #nav #menus .nav-button .long a .totopbtn span { border-radius : 35px ; display : flex; justify-content : center; align-items : center; transition : 0.3s ; white-space : nowrap; } #page-header #nav #menus .nav-button .long a .totopbtn :hover { border-radius : 35px ; height : 30px ; } #nav #search-button { padding-left : 0 ; } #page-header #nav .nav-button { margin-left : 0.5rem ; padding : 0 ; } #page-header :not (.is-top-bar ) #nav-totop a { display : none; } #search-button a .site-page .social-icon .search span { display : none; } #nav #blog-info { overflow : unset; }
新建[BlogRoot]/source/js/nav_menu.js
window .onscroll = percent; function percent ( ) { let a = document .documentElement .scrollTop || window .pageYOffset , b = Math .max ( document .body .scrollHeight , document .documentElement .scrollHeight , document .body .offsetHeight , document .documentElement .offsetHeight , document .body .clientHeight , document .documentElement .clientHeight ) - document .documentElement .clientHeight , result = Math .round ((a / b) * 100 ), btn = document .querySelector ("#percent" ); result <= 99 || (result = 99 ), (btn.innerHTML = result); } document .getElementById ("page-name" ).innerText = document .title .split (" | 张时贰" )[0 ];
修改主题配置文件_config.butterfly.yml,引入css、js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/nav_menu.css"> bottom: # - <script src="xxxx"></script> + - <script data-pjax src="/js/nav_menu.js"></script>
为了处理顶栏一闪而过的 bug 修改[BlogRoot]/themes/butterfly/source/js/main.js,注意有引用线上 版本的话一定要使用本地版本改完再自行上传线上版本
if (currentTop > 56) { + $header.classList.add('is-top-bar') if (isDown) { if (currentTop - $header.classList.remove('nav-fixed', 'nav-visible') + $header.classList.remove('is-top-bar') }
修改[BlogRoot]/themes/butterfly/layout/includes/header/index.pug
其中nav-visible可以控制默认显示的是站点标题还是导航栏菜单。
if top_img !== false - var imgSource = top_img && top_img.indexOf('/') !== -1 ? `background-image: url('${url_for(top_img)}')` : `background: ${top_img}` - var bg_img = top_img ? imgSource : '' - var site_title = page.title || page.tag || page.category || config.title - - var isHomeClass = is_home() ? 'full_page' : 'not-home-page' + - var isHomeClass = is_home() ? 'full_page nav-fixed nav-visible' : 'not-home-page' - is_post() ? isHomeClass = 'post-bg' : isHomeClass else - var isHomeClass = 'not-top-img'
全部替换[BlogRoot]/themes/butterfly/layout/includes/header/nav.pug
nav#nav span#blog-info .back-home-button(tabindex='-1') i.back-home-button-icon.fas.fa-grip-vertical .back-menu-list-groups .back-menu-list-group .back-menu-list-title 网页 .back-menu-list a.back-menu-item(href='/', title='前往博客主页', target='_blank', one-link-mark='yes') img.back-menu-item-icon(src='https://q1.qlogo.cn/g?b=qq&nk=1310446718&s=5') span.back-menu-item-text 博客 a.back-menu-item(href='https://status.zhsher.cn/status/friend', rel='external nofollow', title='前往友链监控', target='_blank', one-link-mark='yes') img.back-menu-item-icon(src='https://zhsher.cn/Hexo_img/config/nav_uptime.webp') span.back-menu-item-text 友链监控 a.back-menu-item(href='https://rv.zhsher.cn/Game_box/game/', rel='external nofollow', title='前往游戏盒', target='_blank', one-link-mark='yes') img.back-menu-item-icon(src='https://zhsher.cn/Hexo_img/config/nav_box.webp') span.back-menu-item-text 游戏盒 .back-menu-list-group .back-menu-list-title 项目 .back-menu-list a.back-menu-item(href='https://github.com/GC-ZF/hexo-hot-article', title='前往阅读统计', target='_blank', rel='noopener nofollow', one-link-mark='yes') img.back-menu-item-icon(src='https://zhsher.cn/Hexo_img/config/nav_article.webp') span.back-menu-item-text 占位 a#site-name(href=url_for('/')) .title #[=config.title] i.fa-solid.fa-house div.mask-name-container center(id="name-container") a(id="page-name" href="javascript:rmf.scrollToTop()") PAGE_NAME #menus if (theme.algolia_search.enable || theme.local_search.enable || theme.docsearch.enable) div.nav-button#search-button a.site-page.social-icon.search(href="javascript:void(0);") i.fas.fa-search.fa-fw span=' '+_p('search.title') if theme.darkmode.enable && theme.darkmode.button div.nav-button#darkmode_navswitch a.darkmode_switchbutton(type="button" title=_p('rightside.night_mode_title') onclick="rmf.switchDarkMode()") i.fas.fa-adjust div.nav-button#nav-totop a.totopbtn i.fas.fa-arrow-up span#percent(onclick="btf.scrollToDest(0,500)") 0 !=partial('includes/header/menu_item', {}, {cache: true}) #toggle-menu a.site-page i.fas.fa-bars.fa-fw
社交卡片 来源:安知鱼 - 生活明朗 万物可爱 站点扒的
全部替换[BlogRoot]/themes/butterfly/layout/includes/widget/card_author.pug
if theme.aside.card_author.enable .card-widget.card-info .author-info-top .card-info-avatar a.avatar-img(href='/about') img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar") .author-status-box .author-status g-emoji.g-emoji(alias='palm_tree', fallback-src='https://zhsher.cn/Hexo_img/config/social_card2.webp') 🌴 span On vacation .author-info__sayhi#author-info__sayhi h1.author-info__name= config.author .author-info__description!= theme.aside.card_author.description || config.description .banner-button-group a.banner-button(href='/about') i.fas.fa-circle-arrow-up-right span.banner-button-text 了解更多 if(theme.social) .card-info-social-icons.is-center !=fragment_cache('social', function(){return partial('includes/header/social')})
新建[BlogRoot]/source/css/social_card.css
div #author-info__sayhi { text-align : left; background : var (--zhsher-white-op); color : var (--font-color); border : var (--style-border); font-size : 12px ; margin-right : auto; padding : 5px 8px ; border-radius : 12px ; width : fit-content; display : inline; margin-left : -1px } .card-widget .author-info-top { margin : 15px auto 0 ; display : flex; justify-content : center } .card-widget .card-info-avatar { display : inline-block; position : relative } .card-widget .card-info .banner-button-group { margin : 5px 0 ; display : flex } #aside-content .card-info .banner-button { height : 40px ; width : 100% ; border-radius : 20px ; justify-content : center } .card-widget .card-info .banner-button-group .banner-button { padding : 20px 12px ; background : var (--zhsher-theme); border-radius : 12px ; color : var (--zhsher-white); display : flex; align-items : center; z-index : 1 ; transition : all .3s ease 0s ; cursor : pointer } .card-widget .card-info .banner-button-group .banner-button .fas .fa-circle-arrow-up-right { font-size : 1.3rem ; margin-right : 10px } .card-widget .card-info .banner-button-group .banner-button :hover { background : var (--zhsher-main-op-deep); color : var (--zhsher-white) } .card-info-avatar .avatar-img { width : 100px ; height : 100px ; display : block } .card-info-avatar .author-status-box { position : absolute; bottom : 0 ; left : calc (100% - 28px ); width : 28px ; height : 28px ; border : var (--style-border); border-radius : 2em ; background-color : var (--zhsher-card-bg); transition : .3s ; overflow : hidden } .card-info-avatar .author-status-box .author-status { display : flex; align-items : center; justify-content : center; height : 28px ; padding : 0 5px } .card-info-avatar .author-status-box :hover { width : 105px } .card-info-avatar .author-status-box :hover .author-status span { width : 105px ; margin-left : 4px } .card-info-avatar .author-status-box .author-status span { width : 0 ; font-size : 12px ; height : 100% ; overflow : hidden; text-overflow : ellipsis; white-space : nowrap; transition : .3s } #aside-content > .card-info { background : #fff url (https://img02.anheyu.com/adminuploads/1/2022/10/26/6358a07bf21fc.webp ) top -24% center no-repeat; position : relative } [data-theme=dark] #aside-content > .card-info { background : var (--zhsher-card-bg) } @media screen and (max-width : 992px ) { #aside-content > .card-info { background-size : 100% 70% } } .card-widget .author-info__name { line-height : 1.5em ; margin : 4px 0 }
新建[BlogRoot]/source/js/social_card.js
var zhsher = { getTimeState : function ( ) { var element = (new Date ).getHours (), time = "" ; return 0 <= element && element <= 5 ? time = "晚安😴" : 5 < element && element <= 10 ? time = "早上好👋" : 10 < element && element <= 14 ? time = "中午好👋" : 14 < element && element <= 18 ? time = "下午好👋" : 18 < element && element <= 24 && (time = "晚上好👋" ), time }, sayhi : function ( ) { var element = document .getElementById ("author-info__sayhi" ); element && (element.innerHTML = zhsher.getTimeState () + "!我是" ) } } zhsher.sayhi ();
修改主题配置文件_config.butterfly.yml,引入css、js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/social_card.css"> bottom: # - <script src="xxxx"></script> + - <script data-pjax src="/js/social_card.js"></script>
随便逛逛(未启用仅记录) 原文地址:Hexo的Butterfly魔改:随机网页跳转(无缝版) | 张洪Heo
新建[BlogRoot]/themes/butterfly/scripts/helpers/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 || 'zhheo/random.js' , data : `var posts=${JSON .stringify(posts)} ;function toRandomPost(){pjax.loadUrl('/'+posts[Math.floor(Math.random() * posts.length)]);};` } })
没有开启pjax用下面的代码
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 || 'zhheo/random.js' , data : `var posts=${JSON .stringify(posts)} ;function toRandomPost(){window.open('/'+posts[Math.floor(Math.random() * posts.length)],"_self");};` } })
修改主题配置文件_config.butterfly.yml,引入js文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> bottom: # - <script src="xxxx"></script> + - <script src="/zhheo/random.js"></script>
在需要调用的位置执行toRandomPost()函数即可。
比如任意dom添加onclick="toRandomPost()"
例如主题配置文件_config.butterfly.yml导航栏中需要的位置添加,宝藏博主: javascript:travelling() || fas fa-bus
右侧悬浮按钮刷新页面(未启用仅记录) 借鉴控制台:轻笑Chuckle
新建[BlogRoot]/source/js/refresh.js
function refreshCache ( ){confirm ("是否确定刷新缓存" )&&location.reload (!0 )}
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/refresh.css">
修改[BlogRoot]/themes/butterfly/layout/includes/rightside.pug
mixin rightsideItem(array) each item in array case item + when 'refresh' + button#refresh-cache(type='button',title='刷新缓存',onclick='refreshCache()') - - const hideArray = enable ? hide && hide.split(',') :['readmode','translate','darkmode','hideAside'] + - const hideArray = enable ? hide && hide.split(',') :['readmode','translate','darkmode','hideAside','refresh']
人潮汹涌轮播组件(未启用仅记录) 插件地址:hexo-butterfly-swiper-anzhiyu-pro - npm
安装
npm install hexo-butterfly-swiper-anzhiyu-pro --save
修改配置文件 _config.yml,在最下面添加
swiper: enable: true randomenable: true priority: 5 enable_page: / timemode: date layout: type: id name: home_top index: 1 category: - name: 前端 path: /categories/前端/ shadow: var(--anzhiyu-shadow-blue) class: blue icon: fas fa-dove - name: 大学 path: /categories/大学/ shadow: var(--anzhiyu-shadow-red) class: red icon: fas fa-burn - name: 生活 path: /categories/生活/ shadow: var(--anzhiyu-shadow-green) class: green icon: fas fa-book default_descr: 再怎么看我也不知道怎么描述它的啦! swiper_css: https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu-pro/lib/swiper.min.css swiper_js: https://npm.elemecdn.com/anzhiyu-blog@1.1.6/js/swiper.min.js custom_css: https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu-pro/lib/swiperstyle.css custom_js: https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu-pro/lib/swiper_init.js gsap_js: https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/gsap/3.9.1/gsap.min.js people_js: https://npm.elemecdn.com/hexo-butterfly-swiper-anzhiyu-pro/lib/people.min.js categorygroup_css: https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu-pro/lib/categoryGroup.css
新建[BlogRoot]/source/css/home_top.css
#home_top { margin : 1rem auto 0 ; padding : 0px 15px ; max-width : 1450px ; width : 100% ; }
修改主题配置文件_config.butterfly.yml,引入css文件
inject: head: # - <link rel="stylesheet" href="/xxx.css"> + - <link rel="stylesheet" href="/css/home_top.css">
修改[BlogRoot]/themes/butterfly/layout/includes/header/index.pug,最后一行加
使用时在文章的front_matter中添加swiper_index、top_group_index配置项
--- title: 文章标题 date: 创建日期 updated: 更新日期 cover: 文章封面 description: 文章描述 swiper_index: 1 top_group_index: 1 ---
八、部署至服务器 注意一:如果仅是玩Hexo博客,不需要浪费这个钱购买服务器,使用Github、Vercel等这类托管服务即可
注意贰:此方法已过时,因为仅是服务器部署且比较繁琐,第六小节中的自动化部署无脑简单方便更适合实际生产!
2022.05.31日,没错!我买服务器啦!!!微信里加了各种平台的运营、经销商之类,早上告我腾讯云618在搞促销,我当时在上课没回复,可能以为我没兴趣,中午转了我个红包?!”帮我完成一下考核,随便买个域名”,小张岂能是无功受禄之人?”不用了,我买个服务器给你冲KPI吧!”,废话不多说开始教学,从买服务器开始吧
准备 域名:阿里云域名28元一年
服务器:腾讯云新用户首购45元一年,Ubuntu 轻量型 2核2G 40GB 4M带宽 300G流量 。博客轻量型足够,毕竟学生党嘛
shell工具(仁者见仁智者见智,不分好坏):Aechoterm(首推)=CMD+vim命令=XShell(连接服务器)+Xftp 6(与服务器互传文件)+VScode或Notepad++(编辑服务器里的文件)
先前部署在Github上,不需要备案,但是服务器建在国内就必须做了
在服务器厂商(阿里云/腾讯云)申请ICP备案(十天左右通过审核,ICP必须备否则域名无法访问) 给域名申请SSL证书 ICP备案通过后在全国公安机关互联网站安全管理服务平台 进行公安备案(公安备案看地方,原则上是强制性的,但有的地方不管,博客备非交互式的www服务,如果安装了评论则备交互式且需要面审) 这部分全是提交申请也没什么好写的,参考:腾讯云完整建站过程 、阿里云域名SSL证书申请 ,之后就可以部署服务器了,也可以先部署只是没ICP备案,部署好网站打不开(如果你和我一样在写教程,截图中公网IP不要暴露)
安装宝塔 买下服务器先重置密码
打开命令行窗口连接服务器:ssh root@公网IP,输入密码,如果你不是CentOS,宝塔面板官网 看一下安装指令
yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh ed8484bec
确认安装宝塔,输入y等待执行完即可,返回信息如下。这个窗口不要关,第五行外网地址,第七、八行是账号密码
success ================================================================== Congratulations! Installed successfully! ================================================================== 外网面板地址: http://服务器ip:8888/5b50213c 内网面板地址: http://服务器ip:8888/5b50213c username: mpspyztn password: 14871f82 If you cannot access the panel, release the following panel port [8888] in the security group 若无法访问面板,请检查防火墙/安全组是否有放行面板[8888]端口 ================================================================== Time consumed: 0 Minute!
在防火墙为宝塔添加端口8888,阿里叫添加安全组
接下来访问外网地址http://服务器ip:8888/5b50213c,第一次进来默认安装LNMP,为我们一键安装所需要的环境。顺便在面板设置里改下登录用户名和密码
方法一 Github Action 注意:原理及优化已在第六小节自动化部署 中总结,方法一已过时
视频教程:自动部署到服务器和github page bilibili 。不得不多说,看了一些其它方法,卷二兔是最省事最简单无脑的教学(包括之前的教学)
打开宝塔面板,输入自己的域名(上文域名已做好解析)
新建[BlogRoot]/.github/workflows/autodeploy.yml,51~53行为Github用户名和邮箱,68行宝塔根目录
name: 自动部署 on: push: branches: - main release: types: - published jobs: checkout: runs-on: ubuntu-latest steps: - name: 检查分支 uses: actions/checkout@v2 with: ref: main - name: 安装 Node uses: actions/setup-node@v1 with: node-version: "12.x" - name: 安装 Hexo run: | export TZ='Asia/Shanghai' npm install hexo-cli -g - name: 缓存 Hexo uses: actions/cache@v1 id: cache with: path: node_modules key: ${{runner.OS}}-${{hashFiles('**/package-lock.json')}} - name: 安装依赖 if: steps.cache.outputs.cache-hit != 'true' run: | npm install --save git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly - name: 生成静态文件 run: | hexo clean hexo generate - name: 部署到github pages run: | git config --global user.name "xxxx" git config --global user.email "xxxx@gmail.com" # git clone https://github.com/xxx/xxx.github.io.git .deploy_git # 此处务必用HTTPS链接。SSH链接可能有权限报错的隐患 # =====注意.deploy_git前面有个空格===== # 这行指令的目的是clone博客静态文件仓库,防止Hexo推送时覆盖整个静态文件仓库,而是只推送有更改的文件 # 我注释掉了是为了刷新整个仓库,也可以选择不注释掉,但是可能出现没有识别到的情况 hexo deploy - name: 部署到云服务器 uses: cross-the-world/scp-pipeline@master with: host: ${{ secrets.USER_HOST }} user: ${{ secrets.USER_NAME }} pass: ${{ secrets.USER_PASS }} connect_timeout: 10s local: './.deploy_git/*' remote: /www/wwwroot/zhsher.cn
在博客备份的仓库,注意是备份 ,不是渲染好的静态页面github.io仓库,添加Secrets
回到博客路径下
git add . git commit -m "添加Action" git push
如果这里显示到自动部署,等待执行完毕后为绿色则部署成功
方法二 原理:通过在服务器内创建Git仓库,利用Git钩子将文件显示在站点路径下
参考:
命令行或者宝塔面板操作都可以,这里以命令操作为例
环境搭建-服务器端配置 因为服务器也需要搭建环境,和我们的本地是一样的,连接服务器后操作
服务器安装git(ubuntu系统自带git)
添加用户
设置/etc/sudoers文件权限
编辑/etc/sudoers
输入 i 进入 insert 模式 ,找到 root ALL=(ALL) ALL ,在其下方加入一行 git ALL=(ALL) ALL
变更/etc/sudoers文件权限
设置git账户密码
切换git账户,创建 ~/.ssh 文件夹和 ~/.ssh/authorized_keys 文件
su git mkdir ~/.sshvim ~/.ssh/authorized_keys
输入 i 进入 insert 模式,将电脑本地的id_rsa.pub公钥复制进去(可以和Github密钥公用一个或者重新建一个),按 ESC ,输入 :wq ,保存文件
配置权限
chmod 600 /home/git/.ssh/authorized_keyschmod 700 /home/git/.ssh
测试,在本地电脑端连接,输入yes
ssh -i ~\.ssh\私钥文件名 git@服务器ip地址或域名
以上服务器端Git已配置好,相当于在自己的服务器创建了一个Github用户及密码(root权限太高所以用git用户操作),接下来就是新建仓库
切换root账户
创建仓库目录,在var目录下创建repo作为Git仓库目录并添加权限
mkdir /var/repo chown -R git:git /var/repo chmod -R 755 /var/repo
创建 hexo目录作为网站根目录
mkdir /www/wwwroot/hexo chown -R git:git /www/wwwroot/hexo chmod -R 755 /www/wwwroot/hexo
创建git仓库
cd /var/repogit init --bare hexo.git
因为Linux系统下,Git仓库文件不会显示存在,钩子就是说把hexo.git这个仓库的文件内容显示在/www/wwwroot/hexo目录下
编辑Git钩子
vim /var/repo/hexo.git/hooks/post-receive
按i进入编辑模式,添加下面的代码,按esc输入:wq 保存
git --work-tree=/www/wwwroot/hexo --git-dir=/var/repo/hexo.git checkout -f
更改权限
chown -R git:git /var/repo/hexo.git/hooks/post-receivechmod +x /var/repo/hexo.git/hooks/post-receive
配置宝塔 宝塔面板中网页->添加站点。注意根目录设置!!!
在域名服务商添加解析,地址为自己的服务器公网IP
配置本地部署 修改配置文件 _config.yml,找到deploy,配置自己的公网ip。为了测试先注释掉Github仓库
deploy: - type: git repository: tecent: git@xxx.xx.xxx.xxx:/var/repo/hexo.git branch: main
hexo clean & hexo g & hexo d三连上去,上传成功在面板文件的/www/wwwroot/hexo查看
设置同时上传服务器与Github,注意格式与之前不同!我的踩坑记录:appear a new branch?how do I do that? · Issue #258 、appear a new branch?how do I do that · Discussion #4988
deploy: - type: git repository: github: https://github.com/xxx/xxx.github.io.git,main tecent: root@xxx.xx.xxx.xxx:/var/repo/hexo.git,master
SSL证书添加 在阿里云下载Nginx格式证书
宝塔面板为网站添加证书
添加备案信息 修改主题配置文件_config.butterfly.yml,将备案信息添加至页脚
footer: owner: enable: true since: 2022 custom_text: <div><a onclick="window.open('https://beian.miit.gov.cn/#/Integrated/index')" class="footer-a">晋ICP备2022005322号</a></div> copyright: true
特别鸣谢 一百个Chocolate博客搭建整理以及部分魔改,他的博客里还有好多好多魔改,大家可以去参考参考,他有的都取消了,可能美化的终极就是简化吧哈哈哈(就是因为这个学长所以学的Hexo!)
你真是一个美好的人类,B站系列教程及博客,对萌新简直太友好!
小冰老师系列教程
Akilarの糖果屋系列教程
Heo哥
Leonus
轻笑Chuckle
安知鱼
Ariasaka
心流
完结撒花,以上有任何看不懂的地方,可以直接评论或者滴滴我的QQ