记录 Hexo 和 butterfly 搭建个人博客的过程
前世今生 关于前言 阅读本篇文章,你可以收获什么?
至少把环境跑起来吧。。。不然我写这个有啥意义啊喂:weary:
en,你还可以对工程搭建有一丢丢的了解
还可以对主题开发有一丢丢的了解,虽然了解了也没啥用:laughing:
还可以get一丢丢的美化技巧:leopard:
以及我的一些心路历程。。。
关于站点 尝试过自己写一个博客,springboot
+ vue
+ nuxt
折腾来折腾去,耗费精力还是没有实现。
尝试过halo
、wordpress
,安装各种主题,blocksy
、Zibll
等,耗费经理还是没有实现。
尝试过在各大论坛写文章,CSDN,简书,掘金等,耗费精力还是没有坚持下去。
也尝试了很多其他的静态站点生成器:Jerry
、VitePress
、VuePress
、hexo+next
等等
关于SSG的技术选型
Nanoc
Middle Man App
Hexo ← 宠幸他 :heart:
DocPad
Hugo
Jekyll
Octopress
Harp
Sculpin
Wintersmith
关于域名 nbchen.com
,好早就用过这个名字了,年少张狂,意气风发
随着头发越掉越多,愈发觉得自己是个 臭弟弟
大帅比,就感觉要低调,谦逊。
故时常对自己 德不配位
恰到好处的 ID 感到惭愧
又因对自己第一个域名有着特殊的 XP
情感
所以在某个 大脑宕机
灵机一动的夜晚,直接买了十年
中间还用过 jiangnan.ink
、lubandadada.site
、等多个域名,特此纪念!
与自己定个十年之约 :clock10:
环境准备
工欲善其事,必先利其器
整体环境
windows环境
1 2 3 4 5 6 7 git config --global user.name 'your_name' git config --global user.email 'your_email' ssh-keygen -t rsa -C 'your_email'
备案相关
安装hexo生成站点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 npm install hexo-cli -g hexo init blog hexo clean && hexo g && hexo s hexo clean && hexo g && hexo d hexo new post -p "数据存储/数据库/MySQL.md" hexo new draft "draft-name" hexo s --drafts
安装butterfly主题 1 2 3 4 5 6 7 8 9 10 npm i hexo-theme-butterfly git clone -b master https://github.com/jerryc127/hexo-theme-butterfly .git themes/butterfly git clone -b dev https://github.com/jerryc127/hexo-theme-butterfly .git themes/butterfly npm install hexo-renderer-pug hexo-renderer-stylus --save
强烈推荐的操作: (之后的教程也都是基于该步骤进行) 拷贝 butterfly 主题目录下的 _config.yml
到根目录下,命名为 _config.butterfly.yml
配置主题 :修改 Hexo 根目录下的 _config.yml
,把主题改为 butterfly
升级主题 :npm update hexo-theme-butterfly
(适用于npm方式;git直接克隆后改动源码的想哭):cry:
站点配置 站点语言 修改站点配置文件 _config.yml
主题支持三种语言
default(en)
zh-CN (简体中文)
zh-TW (繁体中文)
网站资料 修改网站各种资料,例如标题、副标题和邮箱等个人资料,请修改博客根目录的_config.yml
1 2 3 4 5 6 7 8 9 10 11 12 title: 一个蹒跚学步的架构师 subtitle: '为何我身处人群,却时感孤独' description: '学习是一被子的事,被子外只有学习两个字' keywords: java,架构师 author: 一个蹒跚学步的架构师 language: zh-CN timezone: 'Asia/Shanghai' url: https://nbchen.com
主题配置
该小节基本上是基于配置项设置自己喜欢的风格,不会涉及源码改动
导航设置 导航栏元信息:修改主题配置文件 _config.butterfly.yml
1 2 3 4 5 6 nav: logo: display_title: true fixed: true
导航栏菜单:修改主题配置文件 _config.butterfly.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 menu: 首页: / || fas fa-home 归档: /archives/ || fas fa-archive 标签: /tags/ || fas fa-tags 分类: /categories/ || fas fa-folder-open 娱乐||fas fa-list: 音乐: /music/ || fas fa-music 照片: /photo/ || fa-solid fa-image 电影: /movies/ || fas fa-video 友链: /link/ || fas fa-link 闲言: /write/ || fa-solid fa-feather-pointed 留言: /talk2me/ || fas fa-comment-dots 关于: /about/ || fas fa-heart
代码块设置 Butterfly 支持6种代码高亮样式:
darker
pale night
light
ocean
mac
mac light
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 code_blocks: theme: light macStyle: true height_limit: 100 word_wrap: false copy: true language: true shrink: false fullpage: false
还可以自定义代码配色
修改站点配置文件 _config.yml
修改主题配置文件 _config.butterfly.yml
1 2 3 4 5 6 7 code_blocks: theme: false inject: head: - <link rel="stylesheet" href="/self/duotone.css">
代码样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 :root { --hl-color : #728fcb ; --hl-bg : #faf8f5 ; --hltools-bg : xxxxxxx; --hltools-color : xxxxxxx; --hlnumber-bg : xxxxxxx; --hlnumber-color : xxxxxxxx; --hlscrollbar-bg : xxxxx; --hlexpand-bg : xxxxxxx }
社交图标
图片设置 站点图标 1 favicon: /img/favicon.png
头像 1 2 3 4 avatar: img: /img/butterfly-icon.png effect: false
顶部图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 disable_top_img: false default_top_img: index_img: archive_img: tag_img: tag_per_img: category_img: category_per_img: footer_img: false background: cover: index_enable: true aside_enable: true archives_enable: true default_cover:
文章封面
文章封面的获取顺序 Front-matter 的 cover > 配置文件的 default_cover > false
页脚的背景图片 1 2 3 4 5 6 7 8 9 10 11 12 footer_img: false
可以设置颜色的
站点背景 可以设置颜色和图片地址 图片格式: url(http://xxxxxx.com/xxx.jpg )
首页设置 文章元信息显示 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 post_meta: page: date_type: created date_format: date categories: true tags: false label: true post: position: left date_type: both date_format: date categories: true tags: true label: true
首页顶部图大小 默认的显示为全屏,网站信息会居中显示
1 2 3 4 5 6 7 8 9 10 index_site_info_top: index_top_img_height:
注意:index_top_img_height
的值不能使用百分比。 2 个都不填的话,会使用默认值
网站副标题打字机 可设置主页中显示的网站副标题或者喜欢的座右铭。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 subtitle: enable: true effect: true typed_option: source: false sub: - 山高水长,怕什么来不及,慌什么到不了 - 生命只有一次, 你要活得畅快淋漓
首页卡片布局
首页文章摘要 主页文章节选只支持自动摘要
和文章页description
。
1 2 3 4 5 6 7 8 9 index_post_content: method: 3 length: 500
文章设置 文章TOC 在侧边栏显示 TOC(文章目录)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 toc: post: true page: false number: true expand: false style_simple: false scroll_percent: true
文章版权 1 2 3 4 5 6 7 8 9 10 11 12 post_copyright: enable: true decode: false author_href: license: CC BY-NC-SA 4.0 license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/
如果有文章(例如:转载文章)不需要显示版权,可以在文章 Front-matter 单独设置 copyright: false
文章打赏 在你每篇文章的结尾,可以添加赞助按钮。相关二维码可以自行配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 reward: enable: true text: 赛博打赏 QR_code: - img: /img/site/wechat.png link: text: 微信 - img: /img/site/alipay.png link: text: 支付宝
文章编辑按钮 在文章标题旁边显示一个编辑按钮,点击会跳转到对应的链接去。
1 2 3 4 5 6 7 8 9 post_edit: enable: false url:
相关文章
当文章封面设置为 false 时,或者没有获取到封面配置,相关文章背景将会显示主题色。
相关文章推荐的原理是根据文章 tags 的比重来推荐
1 2 3 4 5 6 7 8 related_post: enable: true limit: 6 date_type: created
文章分页按钮
当文章封面设置为 false 时,或者没有获取到封面配置,分页背景将会显示主题色。
可设置分页的逻辑,也可以关闭分页显示
1 2 3 4 5 # 选择: 1 / 2 / false # 1: “下一篇文章”将链接到旧文章 # 2: “下一篇文章”将链接到新文章 # false: 禁用分页 post_pagination: 1
文章过期提醒
可设置是否显示文章过期提醒,以更新时间为基准。
1 2 3 4 5 6 7 8 9 10 11 12 noticeOutdate: enable: false style: flat limit_day: 365 position: top message_prev: 已经过了 message_next: 天自上次更新,文章内容可能已过时。
文章URL设置 1.修改_config.yml
2.写文章时原信息添加id: 自定义URL
隐藏页面标题 有时候可能想隐藏某个页面的标题,直接在page页面添加样式
1 2 3 4 5 <style> .page-title { display : none; } </style>
页脚设置 页脚博客年份 since
是一个来展示你站点起始时间的选项。它位于页面的最底部。
1 2 3 4 5 6 7 8 9 10 11 12 13 footer: owner: enable: true since: 2024 custom_text: copyright: true
页脚自定义文本 custom_text是一个给你用来在页脚自定义文本的选项。通常你可以在这里写声明文本等,支持 HTML。
1 custom_text: Hi, welcome to my <a href="https://butterfly.js.org/">blog</a>!
对于部分人需要写 ICP 的,也可以写在 custom_text里
1 custom_text: <a href="icp链接"><img class="icp-icon" src="icp图片"><span>备案号:xxxxxx-x</span></a>
页脚徽章 用徽章显示:https://shields.io/badges
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 footer: custom_text: <p> <a style="margin-inline:5px"target="_blank" href="https://hexo.io/"> <img src="https://img.shields.io/badge/Frame-Hexo-blue?style=plastic&logo=hexo" title="博客框架为 Hexo" alt="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=plastic&logo=bitdefender" title="主题采用 Butterfly" alt="Butterfly"> </a> <a style="margin-inline:5px"target="_blank" href="https://github.com/"> <img src="https://img.shields.io/badge/Source-Github-d021d6?style=plastic&logo=GitHub" title="本站项目由 GitHub 托管" alt="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=plastic&logo=Claris" alt="img" title="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可"> </a> </p> copyright: false
侧边栏设置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 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/xxxxxx card_announcement: enable: true content: This is my Blog card_recent_post: enable: true limit: 5 sort: date sort_order: card_newest_comments: enable: false sort_order: limit: 6 storage: 10 avatar: true card_categories: enable: true limit: 8 expand: none sort_order: card_tags: enable: true limit: 40 color: false orderby: random order: 1 sort_order: card_archives: enable: true type: monthly format: MMMM YYYY order: -1 limit: 8 sort_order: card_post_series: enable: true series_title: false orderBy: 'date' order: -1 card_webinfo: enable: true post_count: true last_push_date: true sort_order: runtime_date:
右侧按钮 按钮位置 当开启 chat 聊天服务后,聊天服务的按钮可能会遮挡到右下角的按钮,可以设置按钮的位置。
非必要不建议设置,默认就行
简繁切换 主题内置了一个简单的简繁转换功能,採用一对一的形式配对。遇到一字多繁或者一字多简的情况下,会出现不能正常转换正确的简繁体,请留意。
开启后,右下角会有简繁转换按钮。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 translate: enable: false default: 繁 defaultEncoding: 2 translateDelay: 0 msgToTraditionalChinese: '繁' msgToSimplifiedChinese: '简'
阅读模式 阅读模式下会去掉除文章外的内容,避免干扰阅读。只会出现在文章页面,右下角会有阅读模式按钮。
夜间模式 右下角会有夜间模式按钮
1 2 3 4 5 6 7 8 9 10 11 12 13 14 darkmode: enable: true button: true autoChangeMode: false start: end:
滚动状态百分比 1 2 rightside_scroll_percent: false
按钮排序 可对右下角按钮进行排序
注意: 不要重复
1 2 3 4 5 6 7 8 9 10 rightside_item_order: enable: false hide: show:
全局设置 页面锚点 开启页面锚点后,当你在进行滚动时,页面链接会根据标题 ID 进行替换 (注意: 每替换一次,会留下一个历史记录。所以如果一篇文章有很多锚点的话,网页的历史记录会很多。)
1 2 3 4 5 6 anchor: auto_update: false click_to_scroll: false
图片描述 可开启图片 Figcaption 描述文字显示
优先显示图片的 title 属性,然后是 alt 属性
复制相关 可配置网站是否可以复制、复制的内容是否添加版权信息
1 2 3 4 5 6 7 8 9 copy: enable: true copyright: enable: false limit_count: 150
字数统计 开启字数统计功能,需要安装hexo-wordcount
插件
在 hexo
工作目录下运行 npm install hexo-wordcount --save
or yarn add hexo-wordcount
1 2 3 4 5 6 7 8 9 10 wordcount: enable: false post_wordcount: true min2read: true total_wordcount: true
访问人数 访问 busuanzi 的官方网站查看更多的介绍。
由于 busuanzi 的稳定性问题,偶尔会遇到无法访问的情况,请留意。
文章页的访问人数统计,是通过 busuanzi 这个插件实现的。个别评论系统自带访问人数统计功能,可以在相对应的评论系统配置中进行开启,其会代替 busuanzi 的统计。
1 2 3 4 5 6 7 8 busuanzi: site_uv: true site_pv: true page_pv: true
如果需要修改 busuanzi 的 CDN 链接,可通过 主题配置文件 的 CDN 中的 option 进行修改
1 2 3 CDN: option: busuanzi: xxxxx
数学公式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 math: use: per_page: true hide_scrollbar: false mathjax: enableMenu: true tags: none katex: copy_tex: false
Mathjax 1 2 3 npm uninstall hexo-renderer-marked --save npm install hexo-renderer-kramed --save
katex 卸载hexo默认的 marked插件
1 2 3 4 5 6 npm un hexo-renderer-marked --save # 如果有安装这个的话,卸载 npm un hexo-renderer-kramed --save # 如果有安装这个的话,卸载 npm i hexo-renderer-markdown-it --save # 需要安装这个渲染插件 npm install katex @renbaoshuo/markdown-it-katex #需要安装这个katex插件
在 hexo 的根目录的 _config.yml
中配置
1 2 3 markdown: plugins: - '@renbaoshuo/markdown-it-katex'
搜索设置 主题支持三种搜索方式(algolia_search / local_search / docsearch),你可以选择一种或者多种搜索方式。
本地搜索 1.你需要安装 hexo-generator-searchdb
或者 hexo-generator-search
,根据它的文档去做相应配置
2.把主题配置文件中 search 的 use 配置为 local_search
1 npm install hexo-generator-search --save
3.配置搜索
1 2 3 4 5 6 7 8 search: use: local_search placeholder: local_search: enable: true
分享系统 主题支持两种分享方式,一种是sharejs ,一种是addtoany 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 share: use: sharejs sharejs: sites: facebook,twitter,wechat,weibo,qq addtoany: item: facebook,twitter,wechat,sina_weibo,facebook_messenger,email,copy_link
评论系统
Disqus: 功能强大,但是需要科学上网
Gitment:第一款利用 GitHub Issues 的评论系统,但是作者弃坑了
Valine: 从v1.4.0
后暂停更新,开始闭源,且需要结合LeanCloud
Waline: 从 Valine 衍生的带后端评论系统
畅言:广告占位且强制用户绑定手机号
LiveRe来必力: 科学上网
Utterances: 科学上网
Giscus:依赖Github Discussions
Gittalk 评论: 要用到GitHub OAuth
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 comments: use: gitalk text: true lazyload: false count: false card_post_count: false gitalk: client_id: xx client_secret: xx repo: zuoer96.github.io owner: zuoer96 admin: zuoer96 option:
聊天服务
不想设置在线聊天系统,所以没有整理相关内容
网页收录 如果需要搜索引擎收录网站,可能需要登录对应搜索引擎的管理平台进行提交。 各自的验证码可从各自管理平台拿到
1 2 3 4 5 6 7 8 9 10 11 site_verification:
1 2 3 4 site_verification: - name: google-site-verification content: xxxxx
分析统计 百度统计 1.登录百度统计的官方网站
2.找到你百度统计的统计代码
谷歌分析
广告配置 谷歌广告
美化效果 自定义主题色 可以修改大部分 UI 颜色
修改 主题配置文件
,比如:
颜色值必须被双引号包裹,就像”#000”而不是#000。否则将会在构建的时候报错!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
文字左右对齐 可设置文字向两侧对齐,对最后一行无效
1 2 text_align_justify: false
黑色遮罩 为了避免图片过于鲜艳而导致文字无法阅读,默认为顶部图和页脚添加黑色遮罩
1 2 3 4 mask: header: true footer: true
页面加载动画 preloader 当进入网页时,因为加载速度的问题,可能会导致 top_img 图片出现断层显示,或者网页加载不全而出现等待时间,开启 preloader 后,会显示加载动画,等页面加载完,加载动画会消失。
1 2 3 4 5 6 7 8 9 10 preloader: enable: false source: 1 pace_css_url:
页面美化 会改变 ol
、ul
、h1-h5
的样式
field配置生效的区域
1 2 3 4 5 6 7 8 9 10 11 beautify: enable: false field: post title-prefix-icon: title-prefix-icon-color:
全局字体 可自行设置字体的font-family
1 2 3 4 5 6 7 8 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
博客字体 可自行设置字体的font-family
如不需要配置,请留空。
如不需要使用网络字体,只需要把 font_link
留空就行
1 2 3 4 5 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
打字效果 1 2 3 4 5 6 7 8 9 10 11 12 activate_power_mode: enable: false colorful: true shake: true mobile: false
背景特效 好看的綵带背景,可设置每次刷新更换綵带,或者每次点击更换綵带
1 2 3 4 5 6 7 8 9 10 11 12 13 14 canvas_ribbon: enable: false size: 150 alpha: 0.6 zIndex: -1 click_to_change: false mobile: false
1 2 3 4 5 6 7 canvas_fluttering_ribbon: enable: false mobile: false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 canvas_nest: enable: false color: '0,0,255' opacity: 0.7 zIndex: -1 count: 99 mobile: false
鼠标点击效果
1 2 3 4 5 6 7 8 fireworks: enable: false zIndex: 9999 mobile: false
1 2 3 4 5 6 7 8 click_heart: enable: false mobile: false
1 2 3 4 5 6 7 8 9 10 11 12 13 clickShowText: enable: false text: fontSize: 15px random: false mobile: false
灯箱设置 图片大图查看模式
其他设置 Pjax 当用户点击链接,通过 ajax 更新页面需要变化的部分,然后使用 HTML5 的 pushState 修改浏览器的 URL 地址。
这样可以不用重复加载相同的资源(css/js), 从而提升网页的加载速度。
1 2 3 4 5 6 7 8 pjax: enable: false exclude:
注意:
对于一些第三方插件,有些并不支持 pjax 。你可以把网页加入到 exclude 里,这个网页会被 pjax 排除在外。点击该网页会重新加载网站
使用 pjax 后,一些自己 DIY 的 js 可能会无效,跳转页面时需要重新调用,请参考Pjax 文档
使用 pjax 后,一些个别页面加载的 js/css,将会改为所有页面都加载
Snackbar弹窗 比如代码块复制成功,通过弹窗提示
1 2 3 4 5 6 7 8 9 10 11 snackbar: enable: false position: bottom-left bg_light: '#49b1f5' bg_dark: '#1f1f1f'
Instantpage 当鼠标悬停到链接上超过 65 毫秒时,Instantpage 会对该链接进行预加载,可以提升访问速度。
Pangu 如果你跟我一样,每次看到网页上的中文字和英文、数字、符号挤在一块,就会坐立难安,忍不住想在它们之间加个空格。这个外挂正是你在网路世界走跳所需要的东西,它会自动替你在网页中所有的中文字和半形的英文、数字、符号之间插入空白。
1 2 3 4 5 6 7 pangu: enable: false field: site
PWA 要为Butterfly配上 PWA 特性, 你需要如下几个步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // offline config passed to workbox-build. module.exports = { globPatterns: ['**/*.{js,html,css,png,jpg,gif,svg,webp,eot,ttf,woff,woff2}' ], // 静态文件合集,如果你的站点使用了例如 webp 格式的文件,请将文件类型添加进去。 globDirectory: 'public' , swDest: 'public/service-worker.js' , maximumFileSizeToCacheInBytes: 10485760 , // 缓存的最大文件大小,以字节为单位。 skipWaiting: true , clientsClaim: true , runtimeCaching: [ // 如果你需要加载 CDN 资源,请配置该选项,如果没有,可以不配置。 // CDNs - should be CacheFirst , since they should be used specific versions so should not change { urlPattern: /^https:\/\/cdn\.example\.com\/.*/ , // 可替换成你的 URL handler: 'CacheFirst' } ] }
4.在主题配置文件中开启 pwa 选项。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 pwa: enable: false manifest: apple_touch_icon: favicon_32_32: favicon_16_16: mask_icon:
5.在创建source/
目录中创建manifest.json
文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 { "name": "string" , "short_name": "Junzhou" , "theme_color": "#49b1f5" , "background_color": "#49b1f5" , "display": "standalone" , "scope": "/" , "start_url": "/" , "icons": [ { "src": "images/pwaicons/36.png" , "sizes": "36x36" , "type": "image/png" }, { "src": "images/pwaicons/48.png" , "sizes": "48x48" , "type": "image/png" }, { "src": "images/pwaicons/72.png" , "sizes": "72x72" , "type": "image/png" }, { "src": "images/pwaicons/96.png" , "sizes": "96x96" , "type": "image/png" }, { "src": "images/pwaicons/144.png" , "sizes": "144x144" , "type": "image/png" }, { "src": "images/pwaicons/192.png" , "sizes": "192x192" , "type": "image/png" }, { "src": "images/pwaicons/512.png" , "sizes": "512x512" , "type": "image/png" } ], "splash_pages": null }
你也可以通过 Web App Manifest 快速创建manifest.json。(Web App Manifest 要求至少包含一个 512*512
像素的图标)
Open Graph 在 head 里增加一些 meta 资料,例如缩略图、标题、时间等等。当你分享网页到一些平台时,平台会读取 Open Graph 的内容,展示缩略图,标题等等信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 Open_Graph_meta: enable: true option:
CSS 前缀 有些 CSS 并不是所有浏览器都支持,需要增加对应的前缀才会生效。
开启 css_prefix 后,会自动为一些 CSS 增加前缀。(会增加 20%的体积)
Inject 如想添加额外的 js/css/meta
等等东西,可以在 Inject 里添加,支持添加到 head(</body>
标签之前)和 bottom(</html>
标签之前)。
请注意:以标准的 html 格式添加内容
1 2 3 4 5 6 inject: head: - <link rel="stylesheet" href="/self.css"> bottom: - <script src="xxxx"></script>
CDN 配置文件中最后一部分 CDN,里面是主题所引用到的文件,可自行配置 CDN。(非必要请勿修改,配置后请确认链接是否能访问)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CDN: internal_provider: local third_party_provider: jsdelivr version: false custom_format:
如需修改版本号,可修改主题目录的 ‘plugins.yml’ 中对应插件的 version
请确保你修改的版本号,你所使用的 cdn 有收录
常用插件
文章字数统计和阅读时长统计: hexo-wordcount
文末添加当前文章链接和版权申明: hexo-addlink
图片懒加载: hexo-lazyload-image
生成baidusitemap.xml: hexo-generator-baidu-sitemap
生成sitemap.xml: hexo-generator-sitemap
生成RSS文件: hexo-generator-feed
外链跳转:hexo-external-link
自动对外部链接增加nofollow属性:hexo-autonofollow
为外链添加rel=noopener external nofollow noreferrer
: hexo-filter-nofollow
代码高亮: hexo-prism-plugin
博客压缩: hexo-neat、hexo-allminifier
aplayer音乐播放器:hexo-tag-aplayer
dplayer视频播放器:hexo-tag-dplayer
添加豆瓣读书,电影,游戏页面:hexo-douban
本地搜索,生成search.xml: hexo-generator-searchdb
搜索系统: hexo-algolia、hexo-generator-search
百度站长主动推送: hexo-baidu-url-submit
开启PWA: hexo-offline、hexo-pwa
看板娘:hexo-pelper-live2d
博客文章加密: hexo-blog-encrypt
博客展示pdf: hexo-pdf
添加Steam游戏界面: hexo-steam-games
添加bilibili番剧页面: hexo-bilibili-bangumi
生成随机文章页面: hexo-generator-random
博客添加脑图: hexo-markmap 1 npm install hexo-markmap --save-dev
用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 {% markmap height [depth] %} - Markdown- Syntax{% endmarkmap %} # height: 画布高度 # depth: 可选,自动折叠层数深于 depth 的节点 {% markmap 400px %} - links- **inline** ~~text~~ *styles* - multiline text - `inline code` - ```js console.log('code block'); console.log('code block'); ``` - KaTeX - $x = {-b \pm \sqrt{b^2-4ac} \over 2a}${% endmarkmap %}
在_config.yaml
中配置
1 2 3 hexo_markmap: pjax: true katex: true
在_config_butterfly.yaml
中配置
1 2 3 4 5 6 7 8 9 pjax: enable: true katex: enable: true per_page: false hide_scrollbar: true
文章置顶:hexo-generator-index-pin-top 1 2 3 4 5 6 7 npm uninstall hexo-generator-index --save npm install hexo-generator-index-pin-top --save 在需要置顶的文章的Front-matter中加上top: true/数字即可, 数字越大,文章越靠前。 top: 1 #这里加一个top就行
文章图片:hexo-asset-img
markdown文章一般用typora,为了本地可以查看,又不影响部署后的图片显示。需要考虑2者的协调。
原理就是:![example](postname/example.jpg) --> {% asset_img example.jpg example %}
1 npm install hexo-asset-img --save
修改_config.yml
1 post_asset_folder: true # false # 启动 Asset 文件夹
生成URL短连接: hexo-abbrlink
原理就是渲染文章时,会将abbrlink
放到文章的原信息
1.安装hexo-abbrlink
1 npm install hexo-abbrlink --save
2._config.yml
1 2 permalink: posts/:abbrlink.html
3._config.butterfly.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 abbrlink: alg: 16 rep: dec drafts: false auto_category: enable: true depth: over_write: false auto_title: false auto_date: false force: false
文章页GPT总结: 待整理 后台管理博客:hexo-admin 1 2 npm install --save hexo-admin 访问: http://localhost:4000/admin
点击setting,点击setup Authentification here
,设置用户名,密码,secret,将下放生成的配置复制到_config.yml
1 2 3 4 5 admin: username: xxxxx password_hash: xxxxxx secret: xxxxxx
设置deploy
创建hexo-deploy.bat
1 2 @echo off call hexo clean && hexo g && hexo d
重启
效果:后台post页面发布博客,发完本地即可访问,deploy页面同步到远程服务器
单篇博文配置 Front-matter 是 markdown 文件最上方以 ---
分隔的区域,用于指定个别档案的变数。
Page Front-matter 用于 页面 配置
Post Front-matter 用于 文章页 配置
页面 Front-matter 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 --- title: date: updated: type: comments: description: keywords: top_img: mathjax: katex: aside: aplayer: highlight_shrink: random: ---
参数说明:
1 2 title: ' ' 可以设置为空字符串,达到隐藏title的目的
date: 【必需】页面创建日期
type: 【必需】标签、分类和友情链接三个页面需要配置
updated: 【可选】页面更新日期
description: 【可选】页面描述
keywords: 【可选】页面关键字
comments: 【可选】显示页面评论模块 (默认 true)
top_img: 【可选】页面顶部图片
1 top_img: false # 设置false可以隐藏顶部图片效果
mathjax: 【可选】显示 mathjax (当设置 mathjax 的 per_page: false 时,才需要配置,默认 false)
katex: 【可选】显示 katex (当设置 katex 的 per_page: false 时,才需要配置,默认 false)
aside: 【可选】显示侧边栏 (默认 true)
aplayer: 【可选】在需要的页面加载 aplayer 的 js 和 css,请参考文章下面的音乐 配置
highlight_shrink: 【可选】配置代码框是否展开 (true/false) (默认为设置中 highlight_shrink 的配置)
random: 【可选】配置友情链接是否随机排序(默认为 false)
文章页 Front-matter 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 --- title: date: updated: tags: categories: keywords: description: top_img: comments: cover: toc: toc_number: toc_style_simple: copyright: copyright_author: copyright_author_href: copyright_url: copyright_info: mathjax: katex: aplayer: highlight_shrink: aside: abcjs: ---
参数说明:
title: 【必需】文章标题
date: 【必需】文章创建日期
updated: 【可选】文章更新日期
tags: 【可选】文章标签
categories: 【可选】文章分类
1 2 3 4 5 6 7 8 9 10 分类是支持父子分类的 并列分类,了解一下: categories: - [Linux] - [Tools] 并列+子分类,再了解一下: categories: - [Linux, Hexo] - [Tools, PHP]
keywords: 【可选】文章关键字
description: 【可选】文章描述
top_img: 【可选】文章顶部图片
cover: 【可选】文章缩略图(如果没有设置 top_img,文章页顶部将显示缩略图,可设为 false/图片地址/留空)
comments: 【可选】显示文章评论模块(默认 true)
toc: 【可选】显示文章 TOC(默认为设置中 toc 的 enable 配置)
toc_number: 【可选】显示 toc_number(默认为设置中 toc 的 number 配置)
toc_style_simple: 【可选】显示 toc 简洁模式
copyright: 【可选】显示文章版权模块(默认为设置中 post_copyright 的 enable 配置)
copyright_author: 【可选】文章版权模块的文章作者
copyright_author_href: 【可选】文章版权模块的文章作者链接
copyright_url: 【可选】文章版权模块的文章连结链接
copyright_info: 【可选】文章版权模块的版权声明文字
mathjax: 【可选】显示 mathjax(当设置 mathjax 的 per_page: false 时,才需要配置,默认 false )
katex: 【可选】显示 katex (当设置 katex 的 per_page: false 时,才需要配置,默认 false )
aplayer: 【可选】在需要的页面加载 aplayer 的 js 和 css,请参考文章下面的音乐 配置
highlight_shrink: 【可选】配置代码框是否展开(true/false)(默认为设置中 highlight_shrink 的配置)
aside: 【可选】显示侧边栏 (默认 true)
abcjs: 【可选】加载 abcjs (当设置 abcjs 的 per_page: false 时,才需要配置,默认 false )
文章排版 Markdown
标题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # H1 ## H2 ### H3 #### H4 ##### H5 ###### H6 除了井号风格,也支持下划线风格(只能1级和2级) Alt-H1 ====== Alt-H2 ------
强调 1 2 3 4 强调,也就是斜体,带有 *星号* 或 _下划线_。 加粗强调,又名粗体,带有**星号**或__下划线__。 加粗强调下划线斜体结合:**星号和_下划线_**。 ~~删除线.~~
列表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 1. 有序列表 2. 有序列表 * 无序列表 3. 有序列表 1. 有序列表 4. 有序列表 段落可以和列表对齐 也可以用加号和减号缩进 + 列表加号 + 列表加号 + 列表减号 - 列表减号 - 列表减号
内嵌HTML 1 <p > 比如段落标签加上键盘效果 <kbd > ctrl</kbd > +<kbd > alt</kbd > +<kbd > del</kbd > .</p >
定义列表 1 2 3 4 5 6 <dl > <dt > 有序列表头</dt > <dd > 有序列表体</dd > <dt > 有序列表头</dt > <dd > 有序列表体</dd > </dl >
链接 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [我是个连接](https://www.baidu.com) [我是个连接,悬浮可以看到标题](https://www.baidu.com "我是链接标题") [我是引用链接,需要配合下面的注引使用][任意不区分大小写的参考文本] [我是相对路径引用](../blob/master/LICENSE) [您可以使用数字作为参考样式的链接定义,指向下方的数字注引][1] 或者留空,[直接使用文字本身作为关联注引的] # 以下为注引,指向上面的连接 [任意不区分大小写的参考文本]: https://www.baidu.com [1]: https://www.baidu.com [直接使用文字本身作为关联注引的]: https://www.baidu.com
图片 1 2 3 4 5 6 7 8 9 10 11 12 悬浮可以看到文字 内联写法: ![图片文字](https://hexo.io/icon/favicon-196x196.png "悬浮可以看到图片上的文字") 引用文本: ![图片文字][这个指向图片注引] # 以下是注引 [这个指向图片注引]: https://hexo.io/icon/favicon-196x196.png "悬浮可以看到图片上的文字"
代码高亮 javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function $initHighlight (block, cls ) { try { if (cls.search (/\bno\-highlight\b/ ) != -1 ) return process (block, true , 0x0F ) + ` class="${cls} "` ; } catch (e) { } for (var i = 0 / 2 ; i < classes.length ; i++) { if (checkCondition (classes[i]) === undefined ) console .log ('undefined' ); } return ( <div > <web-component > {block}</web-component > </div > ) } export $initHighlight;
python
1 2 3 4 5 6 7 8 9 10 11 12 @requires_authorization def somefunc (param1='' , param2=0 ): r'''A docstring''' if param1 > param2: print 'Gre\'ater' return (param2 - param1 + 1 + 0b10l ) or None class SomeClass : pass >>> message = '''interpreter ... prompt'''
没有指定语言
1 没有指明语言,所以没有语法高亮。 但是让我们加入一个<b>标签</b>。
rust
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #[derive(Debug)] pub enum State { Start, Transient, Closed, } impl From <&'a str > for State { fn from (s: &'a str ) -> Self { match s { "start" => State::Start, "closed" => State::Closed, _ => unreachable! (), } } }
json
1 2 3 4 5 6 7 8 9 10 11 12 [ { "title" : "apples" , "count" : [ 12000 , 20000 ] , "description" : { "text" : "..." , "sensitive" : false } } , { "title" : "oranges" , "count" : [ 17500 , null ] , "description" : { "text" : "..." , "sensitive" : false } } ]
html
1 2 3 4 5 6 7 8 9 10 11 12 13 <!DOCTYPE html > <title > Title</title > <style > body {width : 500px ;}</style > <script type ="application/javascript" > function $init ( ) {return true ;} </script > <body > <p checked class ="title" id ='title' > Title</p > </body >
cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <iostream> int main (int argc, char *argv[]) { for (auto i = 0 ; i < 0xFFFF ; i++) cout << "Hello, World!" << endl; char c = '\n' ; unordered_map <string, vector<string> > m; m["key" ] = "\\\\" ; return -2e3 + 12l ; }
sql
1 2 3 4 5 6 7 8 9 10 11 12 CREATE TABLE "topic" ( "id" serial NOT NULL PRIMARY KEY, "forum_id" integer NOT NULL , "subject" varchar (255 ) NOT NULL ); ALTER TABLE "topic"ADD CONSTRAINT forum_id FOREIGN KEY ("forum_id")REFERENCES "forum" ("id");insert into "topic" ("forum_id", "subject")values (2 , 'D''artagnian' );
java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package l2f.gameserver.model;public abstract class L2Char extends L2Object { public static final Short ERROR = 0x0001 ; public void moveTo (int x, int y, int z) { _ai = null ; log("Should not be called" ); if (1 > 5 ) { return ; } } }
css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @font-face { font-family : Chunkfive; src : url ('Chunkfive.otf' ); } body , .usertext { color : #F0F0F0 ; background : #600 ; font-family : Chunkfive, sans; } @import url(print.css);@media print { a [href^=http] ::after { content : attr (href) } }
bash
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #!/bin/bash ACCEPTED_HOSTS="/root/.hag_accepted.conf" BE_VERBOSE=false if [ "$UID " -ne 0 ]then echo "Superuser rights required" exit 2 fi genApacheConf (){ echo -e "# Host ${HOME_DIR} $1 /$2 :" }
ini
1 2 3 4 5 6 7 8 9 10 11 12 [package] name = "some_name" authors = ["Author" ]description = "This is \ a description" [[lib]] name = ${NAME} default = True auto = no counter = 1_000
表格 1 2 3 4 5 | |ASCII |HTML | |----------------|-------------------------------|-----------------------------| |单引号 |`'Isn't this fun?'` |'Isn't this fun?' | |双引号 |`"Isn't this fun?"` |"Isn't this fun?" | |破折号 |`-- is en-dash, --- is em-dash`|-- is en-dash, --- is em-dash|
冒号可用于对齐列
1 2 3 4 5 | 默认左对齐 | 居中 | 右对齐 | | ------------- |:-------------:| -----:| | 文本 | 文本 | 文本 | | 文本 | 文本 | 文本 | | 文本 | 文本 | 文本 |
外部的竖号不写也可以
1 2 3 4 Markdown | Less | Pretty --- | --- | --- *Still* | `renders` | **nicely** 1 | 2 | 3
html的表格
块引用 markdown语法
1 2 3 > 这是一段块引用 > 这是一个很长的行,当它换行时仍然会被正确引用。哦,男孩,让我们继续写,以确保它足够长,可以真正为每个人包装。哦,你可以_把_ **Markdown ** 放到一个块引用中。
水平线 1 2 3 4 5 6 7 8 # 连字符 --- # 星号 *** # 下划线 ___
标签外挂设置 NOTE 1 2 3 {% note [class] [no-icon] [style] %} Any content (support inline tags too.io). {% endnote %}
参数说明:
class: ( default / primary / success / info / warning / danger )
icon: 可配置自定义 icon (只支持 fontawesome 图标, 也可以配置 no-icon )
style: ( simple / modern / flat / disabled )
用法1:风格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 {% note flat %} 默认 提示块标签 {% endnote %} {% note default flat %} default 提示块标签 {% endnote %} {% note primary flat %} primary 提示块标签 {% endnote %} {% note success flat %} success 提示块标签 {% endnote %} {% note info flat %} info 提示块标签 {% endnote %} {% note warning flat %} warning 提示块标签 {% endnote %} {% note danger flat %} danger 提示块标签 {% endnote %}
用法2:图标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 {% note 'fab fa-cc-visa' simple %} 你是刷 Visa 还是 UnionPay {% endnote %} {% note blue 'fas fa-bullhorn' simple %} 2021 年快到了.... {% endnote %} {% note pink 'fas fa-car-crash' simple %} 小心开车 安全至上 {% endnote %} {% note red 'fas fa-fan' simple%} 这是三片呢?还是四片? {% endnote %} {% note orange 'fas fa-battery-half' simple %} 你是刷 Visa 还是 UnionPay {% endnote %} {% note purple 'far fa-hand-scissors' simple %} 剪刀石头布 {% endnote %} {% note green 'fab fa-internet-explorer' simple %} 前端最讨厌的浏览器 {% endnote %}
Gallery 图库集合
1 2 3 4 5 6 7 8 9 10 11 12 13 <div class ="gallery-group-main" > {% galleryGroup name description link img-url %} {% galleryGroup name description link img-url %} {% galleryGroup name description link img-url %} </div > 举例: <div class ="gallery-group-main" > {% galleryGroup '壁纸' '收藏的一些壁纸' '/Gallery/wallpaper' https://i.loli.net/2019/11/10/T7Mu8Aod3egmC4Q.png %} {% galleryGroup '漫威' '关于漫威的图片' '/Gallery/marvel' https://i.loli.net/2019/12/25/8t97aVlp4hgyBGu.jpg %} {% galleryGroup 'OH MY GIRL' '关于OH MY GIRL的图片' '/Gallery/ohmygirl' https://i.loli.net/2019/12/25/hOqbQ3BIwa6KWpo.jpg %} </div >
图库相册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 {% gallery [lazyload],[rowHeight],[limit] %} markdown 图片格式 {% endgallery %} 举例: {% gallery %} markdown 图片格式 {% endgallery %} {% gallery true,220,10 %} markdown 图片格式 {% endgallery %} {% gallery true,,10 %} markdown 图片格式 {% endgallery %} {% gallery %} ![](https://i.loli.net/2019/12/25/Fze9jchtnyJXMHN.jpg ) ![](https://i.loli.net/2019/12/25/ryLVePaqkYm4TEK.jpg ) ![](https://i.loli.net/2019/12/25/gEy5Zc1Ai6VuO4N.jpg ) ![](https://i.loli.net/2019/12/25/d6QHbytlSYO4FBG.jpg ) ![](https://i.loli.net/2019/12/25/6nepIJ1xTgufatZ.jpg ) ![](https://i.loli.net/2019/12/25/E7Jvr4eIPwUNmzq.jpg ) ![](https://i.loli.net/2019/12/25/mh19anwBSWIkGlH.jpg ) ![](https://i.loli.net/2019/12/25/2tu9JC8ewpBFagv.jpg ) {% endgallery %}
内容隐藏:Tag-hide
tag-hide 内的标签外挂 content 内都不建议有 h1 - h6 等标题。
如果你想把一些文字、内容隐藏起来,并提供按钮让用户点击显示。可以使用这个标签外挂。
1 2 3 4 5 6 7 8 9 10 行内: {% hideInline content,display,bg,color %} 块; {% hideBlock display,bg,color %} content {% endhideBlock %} 收缩 {% hideToggle display,bg,color %} content {% endhideToggle %}
Mermaid 1 2 3 4 {% mermaid %} 内容 {% endmermaid %}
Tabs 1 2 3 4 5 6 7 8 9 10 {% tabs Unique name , [index ] % } <!-- tab [Tab caption ] [@icon ] --> Any content (support inline tags too). <!-- endtab --> {% endtabs % }
1 2 {% btn [url],[text],[icon],[color] [style] [layout] [position] [size] %}
InlineImg 1 {% inlineImg [src] [height] %}
Label
Timeline 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 {% timeline title,color %} <!-- timeline title --> xxxxx <!-- endtimeline --> <!-- timeline title --> xxxxx <!-- endtimeline --> {% endtimeline %}
参数说明:
color: default(留空) / blue / pink / red / purple / orange / green
Flink 可在任何界面插入类似友情链接列表效果
1 2 3 {% flink %} xxxxxx {% endflink %}
ABCJS乐谱 配置:
1 2 3 4 5 6 7 abcjs: enable: true per_page: true
用法:
1 2 3 4 {% score %} 乐谱代码 {% endscore %}
Series系列文章 在页面上显示系列文章
1 2 3 4 5 6 7 8 9 10 series: enable: false orderBy: 'title' order: 1 number: true
用法:
1 2 3 4 5 6 {% series %} {% series [series name] %} 在文章的 front-matter 上添加参数 series,并给与一个标识 使用此标签外挂,会把相同标识的文章以列表的形式展示 如果不写 series 标识,则默认为你使用此标签外挂所在的文章的 series 标识
嵌入YouTube视频 插入 YouTube 视频,可以播放
嵌入Vimeo视频 插入响应式或指定大小的 Vimeo 视频。
1 2 {% vimeo video_id [width] [height] %} {% vimeo 124876737 %}
站内嵌入链接 嵌入调整的链接
1 2 {% link text url [external] [title] %} {% link Docs https://butterfly.js.org/ %}
站内嵌入文章 站内文章链接
1 2 {% post_path filename %} {% post_ link filename [title] [escape] %}
使用此标签时,您可以忽略永久链接和文件夹信息,例如语言和日期.
比如: {% post_link how-to-bake-a-cake %}
.
只要帖子的文件名是 how-to-bake-a-cake.md
,即使帖子位于 source/posts/2015-02-my-family-holiday
并且有固定链接 2018/en/how-to-bake-a-cake
.也能起作用
您可以自定义要显示的文本,而不是显示帖子的标题。不支持在 Markdown 语法 []()
中使用 post_path。
帖子的标题和自定义文本默认转义。您可以使用转义选项来禁用转义。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 {% raw %}{% post_link 标签外挂-Tag-Plugins %}{% endraw %} {% post_ link 标签外挂-Tag-Plugins %}# 自定义链接显示文本 alt {% raw %}{% post_link 标签外挂-Tag-Plugins 'Link to a post' %}{% endraw %} {% post_ link 标签外挂-Tag-Plugins 'Link to a post' %}默认转义 {% post_link 标签外挂-Tag-Plugins 'How to use <b > tag in title' %} {% post_ link 标签外挂-Tag-Plugins 'How to use <b > tag in title' %}不转义 {% post_link 标签外挂-Tag-Plugins '<b > bold</b > custom title' false %} {% post_ link 标签外挂-Tag-Plugins '<b > bold</b > custom title' false %}
站内嵌入图片链接 包括帖子资产
1 2 3 4 5 6 7 {% asset_path filename %} {% asset_ img filename [title] %}{% asset_link filename [title] [escape] %} # iframe:嵌入页面,注意这里是嵌入页面,可以是动态的,是可以用的网站 {% iframe url [width] [height] %} {% iframe 'https://butterfly.js.org/' 100% 300px %}
站内嵌入代码 在 source/downloads/code
文件夹中插入代码片段。可以通过配置中的 code_dir 选项指定文件夹位置。
1 {% include_code [title] [lang:language] [from:line] [to:line] path/to/file %}
嵌入 test.js 的全部内容
1 {% include_code lang:javascript test.js %}
仅嵌入第 3 行
1 {% include_code lang:javascript from:3 to:3 test.js %}
嵌入 5 到 8 行
1 {% include_code lang:javascript from:5 to:8 test.js %}
从第5行开始嵌入
1 {% include_code lang:javascript from:5 test.js %}
将第 5 行嵌入到文件末尾
1 {% include_code lang:javascript to:8 test.js %}
嵌入代码块Code Block 1 2 3 {% codeblock [title] [lang:language] [url] [link text] [additional options] %} code snippet {% endcodeblock %}
Extra Options
Description
Default
line_number
显示行号
true
highlight
启用代码突出显示
true
first_line
指定第一行号
1
mark
行突出显示特定行,每个值用逗号分隔。使用破折号指定数字范围 例如:mark:1,4-7,10
会标记 1, 4 to 7 和 10 行。
wrap
代码块用 <table>
包裹。
true
站内嵌入Gist代码片段 1 2 {% gist gist_id [filename] %} {% gist 996818 %}
站内嵌入jsFiddle 1 2 {% jsfiddle shorttag [tabs] [skin] [width] [height] %} {% jsfiddle ccWP7 %}
文章嵌入引用 非常适合在您的帖子中添加引号,并带有可选的作者、来源和标题信息
1 2 3 4 5 6 7 8 9 10 11 12 13 {% blockquote [author[, source]] [link] [source_link_title] %} content {% endblockquote %} 示例: {% blockquote David Levithan, Wide Awake %} Do not just seek happiness for yourself. Seek happiness for all. Through kindness. Through mercy. {% endblockquote %} 示例:带连接 {% blockquote Seth Godin http://sethgodin.typepad.com/seths_blog/2009/07/welcome-to-island-marketing.html Welcome to Island Marketing %} Every interaction is both precious and an opportunity to delight. {% endblockquote %}
文章内联嵌入引用块 1 2 3 {% pullquote [空|left|right] %} content {% endpullquote %}
Raw
有时候想写点前端小 demo,因为代码量实在是太少了,几行 css、几行 javascript;不想放在 codepen 作为引用,也不想单独做一个页面放到主题的 source 文件夹下,于是就有了在 md 文件里直接写的想法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 {% raw %} <style > .styled-div-right { width : 100px ; height : 100px ; background : yellow; } </style > <div class ="styled-div-right" > 我是div</div > <script > (function ( ){ console .log ('我才是正确的md里的javascript' ); })(); </script > {% endraw %}
页面定制
💥 表示动了源码,请慎重食用
标签页 1.hexo根目录执行hexo new page tags
2.在source/tags/index.md
增加type: "tags"
1 2 3 4 5 6 7 8 --- title: 标签 type: "tags" date: 2024-10-11 17:11:44 comments: false orderby: random # 【可选】排序方式 :random - 随机排序 / name - 标签名字排序 / length - 标签数量排序 order: 1 # 【可选】排序次序: 1(升序),-1(降序) ---
分页类 1.hexo根目录执行hexo new page categories
2.在source/categories/index.md
增加type: "tags"
1 2 3 4 5 --- title: 分类 date: 2024-10-11 17:15:22 type: "categories" ---
友链页 1.hexo根目录执行hexo new page link
2.在source/link/index.md
增加type: "link"
1 2 3 4 5 6 --- title: 友情链接 date: 2024-10-11 17:33:48 type: link random: true # 友链随机排序 ---
编辑source/_data/link.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - 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: 社交分享平台
图库页 1.hexo根目录执行hexo new page photo
2.使用标签galleryGroup
表示图库首页,photo
是自定义的图库名称,根据需求命名
1 2 {% galleryGroup '壁紙' '动漫壁纸' '/photo/wallpaper' https://i.loli.net/2019/11/10/T7Mu8Aod3egmC4Q.png %} {% galleryGroup '漫威' '关于漫威的图片' '/Gallery/marvel' https://i.loli.net/2019/12/25/8t97aVlp4hgyBGu.jpg %}
3.使用标签gallery
表示子图库,wallpaper
是自定义的子图库名称,根据需求命名
注意: 手动创建 /photo/wallpaper/index.md
,或者用命令创建 hexo new page wallpaper
,然后将目录移动到photo目录下
1 2 3 4 5 6 7 8 9 10 11 12 {% gallery %} ![material-1.png](https://i.loli.net/2019/11/10/lP3rLNUBaGtSVzc.png) ![material-8.png](https://i.loli.net/2019/11/10/T7Mu8Aod3egmC4Q.png) ![material-6.png](https://i.loli.net/2019/11/10/53eTB2uiNRlXwFP.png) ![material-10.png](https://i.loli.net/2019/11/10/xthHmnbdNerWOqP.png) ![material-3.png](https://i.loli.net/2019/11/10/rJbFpE65tmxPv7R.png) ![material-4.png](https://i.loli.net/2019/11/10/bEJsXxewpOGuRD8.png) ![material-7.png](https://i.loli.net/2019/11/10/71wgohfPHqXRbG9.png) ![material-2.png](https://i.loli.net/2019/11/10/gcnavZbmepS8d4u.png) ![material-5.png](https://i.loli.net/2019/11/10/3wkO7fuQpgda6vz.png) ![material-9.png](https://i.loli.net/2019/11/10/egVhFWopA5mP2Hk.png) {% endgallery %}
404页 主题内置了一个简单的 404 页面,可在设置中开启
本地预览时,访问出错的网站是不会跳到 404 页面的。如需本地预览,请访问 http://localhost:4000/404.html
1 2 3 4 error_404: enable: true subtitle: '页面没有找到' background: /img/error-page.png
说说页
请留意,说说界面只支持原生的 markdown 格式,不支持标签外挂和数学公式
shuoshuo
命名可以自定义
1.hexo根目录执行hexo new page shuoshuo
2.在source/shuoshuo/index.md
增加type: "link"
1 2 3 4 5 --- title: 说说 date: 2018-06-07 22:17:49 type: 'shuoshuo' ---
编辑source/_data/shuoshuo.yml
author 和 avatar可省略,会自动去获取配置文件中的 author 和 avatar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 - author: Butterfly avatar: https://butterfly.js.org/img/avatar.png date: 2024-06-21 23:33:26 content: | This is a sample content for **Author 1**. ![Sample Image](https://via.placeholder.com/150) tags: - tags1 - tags2 - author: Butterfly avatar: https://butterfly.js.org/img/avatar.png date: 2024-06-20 23:33:26 content: | This is a sample content for **Author 2**. ![Sample Image](https://via.placeholder.com/150) tags: - tag2 - tag3 - author: Butterfly avatar: https://butterfly.js.org/img/avatar.png date: 2024-06-19 23:33:26 content: | This is a sample content for **Author 3 **.
参数说明:
author: 【可选】作者名称
avatar: 【可选】作者头像
date: 【必需】日期
content: 【必需】内容( Markdown 格式或者 Html 格式
tags: 【可选】标签
电影页 💥 电影界面使用了插件 hexo-douban
注意:
hexo-douban
会主动生成页面,所以不需要自己创建。
如遇到无法抓取问题,显示 INFO 0 movies have been loaded in xxx ms, because you are offline or your network is bad
,请过段时间再试试,这我也无能为力。
自己搞电影页:
1.创建布局themes\butterfly\layout\includes\page\movies.pug
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 //- movie page //- 主容器 #article-container .author-content-item.like-movie.single.share .card-content //- ._p('电影') 和其他 _p 函数用于返回国际化文本。 .author-content-item-tips=_p('电影') div.author-content-item-title=_p('静下来慢慢') span.inline-word=_p('感受着,') div.author-content-item-title=_p('流淌的') span.inline-word=_p('故事。') div.author-content-bottom .content-bottom .tips=_p('跟 左耳 查看更多书影音') .banner-button-group a.banner-button(href="https://www.douban.com/") i.fas.fa-circle-chevron-right span.banner-button-text=_p('感受更多') .hexo-douban-item-tip p.gradient-text 静下来,感受电影的魅力 //- 样式文件 style. .hexo-douban-item { padding-bottom: 10px; position: relative; clear: both; min-height: 170px; padding: 10px 0; border-bottom: 1px #ddd solid; } @media screen and (max-width: 600px) { .hexo-douban-item { width: 100%; } } .hexo-douban-picture { position: absolute; left: 0; top: 10px; width: 100px; } .hexo-douban-info { padding-left: 120px; } .hexo-douban-meta { font-size: 12px; padding-right: 10px; } .hexo-douban-comments { font-size: 12px; } div if site.data.movies .hexo-douban-show#hexo-douban-item3 each i in site.data.movies each item in i.movie_list .hexo-douban-item .hexo-douban-picture(title=item.name) a(target='_blank', href=url_for(item.link), rel='external nofollow') img(src=url_for(item.cover), data-src=url_for(item.cover), referrerpolicy='no-referrer') .hexo-douban-info .hexo-douban-title(title=item.name) a(target='_blank', href=url_for(item.link), rel='external nofollow')=item.name .hexo-douban-meta=item.date_grade .hexo-douban-comments=item.comment
2.添加布局themes\butterfly\layout\page.pug
1 2 when 'movies' include includes/page/movies.pug
3.添加样式source\css\movies.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 .author-content-item .single .like-movie { height : 19rem ; background : url (/img/cover/movies_cover.png ) no-repeat top; background-size : cover; color : #c2c2c2 ; overflow : hidden; border-radius : 12px ; -webkit-box-shadow : 0 21px 133px 81px #1c1c1c inset; box-shadow : 0 21px 133px 81px #1c1c1c inset; } .author-content-item .card-content { padding : 1rem 2rem ; display : flex; flex-direction : column; height : 100% ; } .author-content-item .card-content .author-content-bottom { margin-top : auto; display : flex; flex-direction : row; flex-wrap : wrap; justify-content : space-between; } .author-content-bottom .banner-button-group { border : 1px solid #535357 ; border-radius : 8px ; padding-right : 3px ; padding-left : 5px ; background : #535357 ; } .banner-button-group a i ,.banner-button-group a span { color : #c2c2c2 ; padding-right : 2px ; } .banner-button-group a :hover { text-decoration : none !important ; } .banner-button-group a :hover i ,.banner-button-group a :hover span { color : #49b1f5 ; } .author-content-item .author-content-item-title { font-size : 36px ; font-weight : bold; line-height : 1 ; margin-bottom : 0.5rem ; } .hexo-douban-item-tip { margin : 0.5rem 0 0.5rem 0 ; border : 1px solid #e3e8f7 ; border-radius : 8px ; background-color : #f7f7f9 ; padding : 0.5rem 0.8rem ; height : 60px ; line-height : 42px ; } .hexo-douban-item-tip .gradient-text { background : linear-gradient (to left, #ff4500 , #ffa500 , #ffd700 , #90ee90 , #0ff , #1e90ff , #9370db , #ff69b4 , #ff4500 ); -webkit-background-clip : text; color : transparent; font-size : 16px ; font-weight : bold; } .hexo-douban-item { border-bottom : none !important ; background : #fff ; border : 1px solid #e3e8f7 ; box-shadow : 0 8px 16px -4px rgba (44 ,45 ,48 ,0.047 ); border-radius : 12px ; margin : 8px 0 ; height : 160px ; min-height : 160px !important ; width : 49% ; overflow : hidden; } #hexo-douban-item3 { display : flex; flex-direction : row; flex-wrap : wrap; justify-content : space-between; } .hexo-douban-item .hexo-douban-picture a { padding : 0 !important ; } .hexo-douban-item .hexo-douban-picture img { margin : 0px !important ; height : 100% !important ; } .hexo-douban-tabs { display : none; } .hexo-douban-title a { border-bottom : 0px !important ; color : #363636 !important ; font-size : 20px ; font-weight : bold; } .hexo-douban-title { overflow : hidden; text-overflow : ellipsis; white-space : nowrap; } .hexo-douban-title a :hover { color : #49b1f5 !important ; background : rgba (0 , 0 , 0 , 0 ) !important ; text-decoration : none !important ; } .hexo-douban-info { padding-left : 130px !important ; margin-right : 0.5rem ; } .hexo-douban-meta { font-size : 0.7rem !important ; color : rgba (60 ,60 ,67 ,0.8 ); margin-top : 0.3rem ; line-height : 1.05 ; } .hexo-douban-comments { line-height : 1.2 ; margin-top : 0.5rem !important ; font-size : 0.8rem !important ; -webkit-line -clamp: 3 ; overflow : hidden; text-overflow : ellipsis; display : -webkit-box; -webkit-box-orient: vertical; } .hexo-douban-picture { height : 100% ; top : 0 !important ; padding : 10px 0 10px 10px ; } .hexo-douban-picture a img { border-radius : 8px !important ; }
4.添加样式_config.butterfly.yml
1 2 3 inject: head: - <link rel="stylesheet" href="/css/movies.css?1">
5.创建页面hexo new page movies
1 2 3 4 5 6 7 8 9 --- title: '' date: 2024-10-20 09:50:22 type: 'movies' comments: false aside: false top_img: false ---
6.配置页面_config.butterfly.yml
1 2 menu: 电影: /movies/ || fas fa-video
7.添加数据source\_data\movies.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 - class_name: 电影推荐 movie_list: - name: 人生大事 link: https://movie.douban.com/subject/35460157/ cover: https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2874262709.webp date_grade: 2022-07-05 / ★★★★★ 力荐 comment: 非常的感人,是一部非常值得看的电影 - name: 长津湖之水门桥 link: https://movie.douban.com/subject/35613853/ cover: https://img2.doubanio.com/view/photo/s_ratio_poster/public/p2846021991.jpg date_grade: 2022-07-04 / ★★★☆☆ 一般 comment: 怎么说呢,和一直以来拍的都差不多,有的镜头还可以,不过看的还是有点生气
音乐页
感觉全局的附着音乐播放器体验一般,我只是想收藏、展示、和分享我觉得好听的歌曲,所以此处不全局展示,只在音乐页展示。
音乐界面使用了插件 hexo-tag-aplayer
1.安装
1 npm install --save hexo-tag-aplayer
2.修改_config.yml
1 2 3 aplayer: meting: true asset_inject: false
3.修改_config.butterfly.yml
1 2 3 4 aplayerInject: enable: true per_page: true
4.添加下面代码到source/music/index.md
1 {% meting "[网易云歌单ID]" "netease" "playlist" "autoplay" "mutex:false" "listmaxheight:400px" "preload:none" "theme:#ad7a86"%}
更优的方案:安知鱼-音乐馆
装备页 💥 1.主题配置文件添加菜单
1 2 menu: 好物: /equipment/ || fas fa-video
2.引入自定义css和js
1 2 3 4 5 6 7 inject: head: - <link rel="stylesheet" href="/css/equipment.css?1"> bottom: - <script src="/js/equipment.js?1"></script>
3.添加自定义的装备页
在 themes\butterfly\layout\page.pug
中添加如下修改
1 2 when 'equipment' include includes/page/equipment.pug
4.在source/css/equipment.css
自定义样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 .equipment-item-content { display : flex; flex-direction : row; flex-wrap : wrap; margin : 0 -8px ; } .equipment-item-content-item { width : calc (25% - 12px ); border-radius : 12px ; border : var (--style-border-always); overflow : hidden; margin : 8px 6px ; background : var (--heo-card-bg); box-shadow : var (--heo-shadow-border); min-height : 400px ; position : relative; } @media screen and (max-width : 1200px ) { .equipment-item-content-item { width : calc (50% - 12px ); } } @media screen and (max-width : 768px ) { .equipment-item-content-item { width : 100% ; } } .equipment-item-content-item-info { padding : 8px 16px 16px 16px ; margin-top : 12px ; } .equipment-item-content-item-name { font-size : 18px ; font-weight : bold; line-height : 1 ; margin-bottom : 8px ; white-space : nowrap; overflow : hidden; text-overflow : ellipsis; width : fit-content; } .equipment-item-content-item-specification { font-size : 12px ; color : var (--heo-secondtext); line-height : 1 ; margin-bottom : 12px ; white-space : nowrap; overflow : hidden; text-overflow : ellipsis; } .equipment-item-content-item-description { line-height : 20px ; color : var (--heo-secondtext); height : 60px ; display : -webkit-box; overflow : hidden; -webkit-line -clamp: 3 ; -webkit-box-orient: vertical; font-size : 14px ; } a .equipment-item-content-item-link { font-size : 12px ; background : var (--heo-gray-op); padding : 4px 8px ; border-radius : 8px ; cursor : pointer; } a .equipment-item-content-item-link :hover { background : var (--heo-main); color : var (--heo-white); } h2 .equipment-item-title { line-height : 1 ; } .equipment-item-description { line-height : 1 ; margin : 4px 0 8px 0 ; color : var (--heo-secondtext); } .equipment-item-content-item-cover { width : 100% ; height : 200px ; background : var (--heo-secondbg); display : flex; justify-content : center; } img .equipment-item-content-item-image { object-fit : cover; height : 100% ; } div #equipment { margin-top : 26px ; } .equipment-item-content-item-toolbar { display : flex; justify-content : space-between; position : absolute; bottom : 12px ; left : 0 ; width : 100% ; padding : 0 16px ; } a .bber-reply { cursor : pointer; }
5.在source/equipment/index.md
设置type
1 2 3 4 5 6 7 --- title: 好物 date: 2024-10-13 16:37:26 aside: false type: equipment ---
6.在 source/dataequipment.yml
添加数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 - class_name: 生产力 description: 提升自己生产效率的硬件设备 equipment_list: - name: 翻新 MacBookPro specification: M1Pro 32G / 1TB description: 屏幕显示效果好、色彩准确、对比度强、性能强劲、续航优秀。可以用来开发和设计。 image: https://p.zhheo.com/YnW8cc2150681686120255749.png!cover link: https://blog.zhheo.com/p/daebc472.html - name: iPhone 13 Pro specification: 白色 / 256G description: 第一代支持promotion的iPhone,A15性能优秀。 image: https://p.zhheo.com/TofzQM2219061686120261484.png!cover link: https://www.apple.com/by/iphone-13-pro/ - class_name: 出行 description: 用来出行的实物及设备 equipment_list: - name: 航宇之星双肩包 specification: 标准版 description: 造型炫酷,包的容量非常大,还有魔术贴位置,我贴上了鸡哥的头像。 image: https://p.zhheo.com/20jaBU2179061686121157367.png!cover link: https://detail.meizu.com/item/pasasjb.html
导航页 💥 一直想要有个导航页面,但是我想直接放到hexo+butterfly,而不是另外开一个工程,然后用子域名挂接的方式,那就开始折腾吧。
参考webstack 和张洪-自定义layout
1.创建导航布局themes\butterfly\layout\webstack.pug
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 - var htmlClassHideAside = theme.aside.enable && theme.aside.hide ? 'hide-aside' : '' - page.aside = is_archive() ? theme.aside.display.archive: is_category() ? theme.aside.display.category : is_tag() ? theme.aside.display.tag : page.aside - var hideAside = !theme.aside.enable || page.aside === false ? 'hide-aside' : '' - var pageType = is_post() ? 'post' : 'page' - pageType = page.type ? pageType + ' type-' + page.type : pageType doctype html html(lang=config.language data-theme=theme.display_mode class=htmlClassHideAside) head include ./includes/head.pug body #body-wrap(class=pageType) header#page-header(class='not-top-img fixed') nav#nav span#blog-info a.nav-site-title(href=url_for('/')) if theme.nav.logo img.site-icon(src=url_for(theme.nav.logo) alt='Logo') if theme.nav.display_title span.site-name=config.title if is_post() a.nav-page-title(href=url_for('/')) span.site-name=(page.title || config.title) #menus if theme.search.use #search-button span.site-page.social-icon.search i.fas.fa-search.fa-fw span= ' ' + _p('search.title') if theme.menu != partial('includes/header/menu_item', {}, {cache: true}) #toggle-menu span.site-page i.fas.fa-bars.fa-fw main .nb-container .nb-sidebar-menu ul#nb-sidebar-menu-item.nb-sidebar-menu-item each i in site.data.webstack li a.nb-sidebar-menu-a(href=`#${i.class_name}` class="smooth-scroll") i.nb-sidebar-menu-icon span.nb-sidebar-menu-title=i.class_name //- //- 子菜单 //- if i.submenu && Array.isArray(i.submenu) && i.submenu.length > 0 //- ul //- each sub in i.submenu //- li //- a.nb-sidebar-menu-a(href=`#${i.class_name}` class="smooth-scroll") //- i.nb-sidebar-menu-icon //- span.nb-sidebar-menu-title=i.class_name if site.data.webstack .nb-card-main each i in site.data.webstack div.nb-card-maodian(id=iclass_name)=i.class_name each item in i.link_list .nb-card .nb-card-icon a(target='_blank',href=url_for(item.link),rel='external nofollow') img(src=url_for(item.icon), data-src=url_for(item.icon), referrerpolicy='no-referrer' width='40', height='40') div .nb-card-header=item.name .nb-card-body=item.text script. // JavaScript 代码 document.addEventListener('DOMContentLoaded', function() { const links = document.querySelectorAll('.smooth-scroll'); links.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); // 阻止默认链接行为 const targetId = this.getAttribute('href').substring(1); // 获取目标 ID const targetElement = document.getElementById(targetId); // 查找目标元素 if (targetElement) { // 平滑滚动到目标元素 targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); }); include ./includes/rightside.pug include ./includes/additional-js.pug
2.创建导航页source\webstack\index.md
1 2 3 4 5 6 --- title: webstack date: 2024-10-13 15:32:03 layout: webstack ---
3.配置导航页_config.butterfly.yml
1 2 3 4 5 menu: 导航: /webstack/ || fa fa-share-alt inject: head: - <link rel="stylesheet" href="/css/webstack.css?1">
4.定制样式source\css\webstack.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 /* 容器 */ .nb-container { width: 100%; height: 100vh; /* background-color: red; */ } /* 侧边栏样式 */ .nb-sidebar-menu { width: 250px; background-color: #2c3e50; /* 深灰色背景 */ color: #ecf0f1; /* 浅色字体 */ height: 100vh; position: fixed; /* 固定在左侧 */ top: 60px; left: 0; overflow-y: auto; /* 滚动条处理 */ box-shadow: 2px 0 5px rgba(0, 0, 0, 0.3); } .nb-sidebar-menu ul { list-style: none; /* 去除默认列表样式 */ padding: 0; margin: 0; } .nb-sidebar-menu-item { padding: 0; } .nb-sidebar-menu-item li { border-bottom: 1px solid #34495e; /* 每个菜单项之间的分割线 */ } .nb-sidebar-menu-a { display: flex; align-items: center; padding: 15px 20px; text-decoration: none; color: #ecf0f1; /* 菜单项文字颜色 */ transition: background 0.3s ease; } .nb-sidebar-menu-a:hover { background-color: #34495e; /* 悬停时背景色 */ cursor: pointer; } .nb-sidebar-menu-icon { margin-right: 10px; /* 图标与文字的间距 */ font-size: 18px; /* 图标大小 */ } .nb-sidebar-menu-title { font-size: 16px; /* 菜单项文字大小 */ } .nb-card-main { margin-left: 250px; /* 根据侧边栏宽度设置左边距 */ padding: 20px; flex: 1; /* 占满剩余空间 */ background-color: #ecf0f1; /* 主内容区背景色 */ min-height: 100vh; /* 保证主内容区至少与视口高度相同 */ display: flex; /* 使用 flex 布局 */ flex-wrap: wrap; /* 自动换行 */ gap: 20px; /* 卡片之间的间距 */ } /* 卡片主区域 */ .nb-card-maodian { /* background-color: red; */ width: 100%; } .nb-card-maodian::before { content: ""; display: inline-block; width: 15px; height: 15px; margin-right: 10px; background-image: url(/img/webstack/tag-icon.png); background-size: contain; /* 保持图像比例 */ background-repeat: no-repeat; /* 不重复图像 */ vertical-align: -2px; } .nb-card { height: 86px; width: 220px; padding: 10px; background-color: #fff; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease, box-shadow 0.3s ease; display: flex; align-items: center; } .nb-card:hover { transform: translateY(-5px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); cursor: pointer; } .nb-card-icon { font-size: 40px; margin-right: 15px; } .nb-card-header { font-size: 14px; font-weight: bold; /* margin-bottom: 10px; */ } .nb-card-body { font-size: 12px; color: #333; }
6.添加数据source\_data\webstack.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 # 常用推荐 # name:卡片名称 # link:卡片链接 # icon: 卡片图标 # text: 备注(最多26个备注,不然会超过) - class_name: test1 link_list: - name: Dribbble link: https://dribbble.com/ icon: /img/webstack/dribbble.png text: 全球UI设计师作品分享平台。 - name: Behance link: https://behance.net/ icon: /img/webstack/behance.png text: Adobe旗下的设计师交流平台,来自世界各地的设计。 - name: Dribbble link: https://dribbble.com/ icon: /img/webstack/dribbble.png text: 全球UI设计师作品分享平台。 - name: Behance link: https://behance.net/ icon: /img/webstack/behance.png text: Adobe旗下的设计师交流平台,来自世界各地的设计。 - class_name: 常用推荐2 link_list: - name: Dribbble link: https://dribbble.com/ icon: /img/webstack/dribbble.png text: 全球UI设计师作品分享平台。 - name: Behance link: https://behance.net/ icon: /img/webstack/behance.png text: Adobe旗下的设计师交流平台,来自世界各地的设计。 - class_name: 常用推荐3 link_list: - name: Dribbble link: https://dribbble.com/ icon: /img/webstack/dribbble.png text: 全球UI设计师作品分享平台。 - name: Behance link: https://behance.net/ icon: /img/webstack/behance.png text: Adobe旗下的设计师交流平台,来自世界各地的设计。 - class_name: 常用推荐4 link_list: - name: Dribbble link: https://dribbble.com/ icon: /img/webstack/dribbble.png text: 全球UI设计师作品分享平台。 - name: Behance link: https://behance.net/ icon: /img/webstack/behance.png text: Adobe旗下的设计师交流平台,来自世界各地的设计。 - class_name: 常用推荐5 link_list: - name: Dribbble link: https://dribbble.com/ icon: /img/webstack/dribbble.png text: 全球UI设计师作品分享平台。 - name: Behance link: https://behance.net/ icon: /img/webstack/behance.png text: Adobe旗下的设计师交流平台,来自世界各地的设计。 - class_name: 常用推荐6 link_list: - name: Dribbble link: https://dribbble.com/ icon: /img/webstack/dribbble.png text: 全球UI设计师作品分享平台。 - name: Behance link: https://behance.net/ icon: /img/webstack/behance.png text: Adobe旗下的设计师交流平台,来自世界各地的设计。 - class_name: 常用推荐7 link_list: - name: Dribbble link: https://dribbble.com/ icon: /img/webstack/dribbble.png text: 全球UI设计师作品分享平台。 - name: Behance link: https://behance.net/ icon: /img/webstack/behance.png text: Adobe旗下的设计师交流平台,来自世界各地的设计。 - class_name: test8 link_list: - name: Dribbble link: https://dribbble.com/ icon: /img/webstack/dribbble.png text: 全球UI设计师作品分享平台。 - name: Behance link: https://behance.net/ icon: /img/webstack/behance.png text: Adobe旗下的设计师交流平台,来自世界各地的设计。
留言板 1.hexo根目录执行hexo new page talk2me
2.在source/talk2me/index.md
增加type: "talk2me"
1 2 3 4 5 6 --- title: 留言板 date: 2018-01-05 00:00:00 type: talk2me ---
留言信箱 旧版 新版
手搓模式:留言页直接写html代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 {% raw %} <style> @media screen and (max-width:530px) { #computer { display:none!important } } @media screen and (min-width:530px) { #mobile { display:none!important } } #article-container img { margin:0 auto 0 } #form-wrap { overflow:hidden; height:447px; position:relative; top:0; transition:all 1s ease-in-out .3s; z-index:0 } #form-wrap:hover { height:1050px; top:-200px } #beforeimg { position:absolute; bottom:126px; left:0; background-repeat:no-repeat; width:530px; height:317px; z-index:-100; pointer-events:none } #afterimg { position:absolute; bottom:-2px; left:0; background-repeat:no-repeat; width:530px; height:259px; z-index:100; pointer-events:none } #envelope { position:relative; overflow:visible; width:500px; margin:0 auto; transition:all 1s ease-in-out .3s; padding-top:200px } #maincontent { width:530px; margin:20px auto 0 } .headerimg { width:100%; overflow:hidden; pointer-events:none } .formmain { background:#fff; width:95%; max-width:800px; margin:auto auto; border-radius:5px; border:1px solid; overflow:hidden; -webkit-box-shadow:0 0 20px 0 rgba(0, 0, 0, .12); box-shadow:0 0 20px 0 rgba(0, 0, 0, .18); pointer-events:none; } .title3 { text-decoration:none; color:#f6d6af } .comments { border-bottom:#ddd 1px solid; border-left:#ddd 1px solid; padding-bottom:20px; background-color:#eee; margin:15px 0; padding-left:20px; padding-right:20px; border-top:#ddd 1px solid; border-right:#ddd 1px solid; padding-top:20px; font-family:Arial, "Microsoft YaHei", "黑體", "宋體", sans-serif } .bottomcontent { text-align:center; margin-top:40px } .bottomimg { width:100%; margin:5px auto 5px auto; display:block; pointer-events:none } .bottomhr { font-size:12px; text-align:center; color:#999 } [data-theme=dark] .formmain { background:#323232 } [data-theme=dark] .comments { background:rgba(90, 90, 90, .8) } </style> <div id="computer"> <div id="maincontent"> <br /> <div id="form-wrap"> <img src="https://npm.elemecdn.com/cover_img/msg/before.webp" id="beforeimg" /> <div id="envelope"> <form> <div class="formmain"> <img class="headerimg" src="https://npm.elemecdn.com/cover_img/msg/U5bb04af32be544c4b41206d9a42fcacfd.webp" /> <div style="padding: 5px 20px;"> <center> <h3 calss="title3">来自小嘉的留言:</h3> </center> <center class="comments"> 有什么想问的? <br />有什么想说的? <br />有什么想吐槽的? <br /> </center> <div class="bottomcontent"> <img class="bottomimg" src="https://npm.elemecdn.com/cover_img/msg/U0968ee80fd5c4f05a02bdda9709b041eE.webp" /> </div> <p class="bottomhr">自动书记人偶竭诚为您服务!</p> </div> </div> </form> </div> <img id="afterimg" src="https://npm.elemecdn.com/cover_img/msg/after.webp" /> </div> </div> </div> <div id="mobile"> <form> <div class="formmain"> <img class="headerimg" src="https://npm.elemecdn.com/cover_img/msg/U5bb04af32be544c4b41206d9a42fcacfd.webp" /> <div style="padding: 5px 20px;"> <center> <h3 class="title3">来自左耳的留言:</h3> </center> <center class="comments"> 有什么想问的? <br />有什么想说的? <br />有什么想吐槽的? <br /> </center> <div class="bottomcontent"> <img src="https://npm.elemecdn.com/cover_img/msg/U0968ee80fd5c4f05a02bdda9709b041eE.webp" class="bottomhr" /> </div> <p class="bottomhr" "="">自动书记人偶竭诚为您服务!</p> </div> </div> </form> </div> {% endraw %}
1.安装npm插件
见:https://github.com/Akilarlxh/hexo-butterfly-envelope (也可以看源码学习一个插件是怎么做的,很简单的功能)
1 npm install hexo-butterfly-envelope --save
2.修改配置文件(站点/主题文件都可以)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 envelope_comment: enable: true cover: https://ae01.alicdn.com/kf/U5bb04af32be544c4b41206d9a42fcacfd.jpg message: - 有什么想问的? - 有什么想说的? - 有什么想吐槽的? bottom: 自动书记人偶竭诚为您服务! height: path: front_matter: title: 留言板 comments: false aside: false
日志页 1.hexo根目录执行hexo new page timeline
2.在source/timeline/index.md
增加type: "timeline"
1 2 3 4 5 6 --- title: 日志 date: 2024-10-17 08:28:51 type: "timeline" ---
关于页 1.hexo根目录执行hexo new page about
2.在source/about/index.md
增加type: "about"
1 2 3 4 5 6 --- title: 关于 date: 2018-01-05 00:00:00 type: about ---
统计页 1.创建charts页
2.引入echarts
1 2 3 inject: head: - <script src="https://npm.elemecdn.com/echarts@4.9.0/dist/echarts.min.js"></script>
或者在页面引入脚本也可以
3.可以在 [Blogroot]\themes\butterfly\scripts\helpers\
目录下新建 charts.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 const cheerio = require ('cheerio' )const moment = require ('moment' )hexo.extend .filter .register ('after_render:html' , function (locals ) { const $ = cheerio.load (locals) const post = $('#posts-chart' ) const tag = $('#tags-chart' ) const category = $('#categories-chart' ) const htmlEncode = false if (post.length > 0 || tag.length > 0 || category.length > 0 ) { if (post.length > 0 && $('#postsChart' ).length === 0 ) { if (post.attr ('data-encode' ) === 'true' ) htmlEncode = true post.after (postsChart (post.attr ('data-start' ))) } if (tag.length > 0 && $('#tagsChart' ).length === 0 ) { if (tag.attr ('data-encode' ) === 'true' ) htmlEncode = true tag.after (tagsChart (tag.attr ('data-length' ))) } if (category.length > 0 && $('#categoriesChart' ).length === 0 ) { if (category.attr ('data-encode' ) === 'true' ) htmlEncode = true category.after (categoriesChart (category.attr ('data-parent' ))) } if (htmlEncode) { return $.root ().html ().replace (/&#/g , '&#' ) } else { return $.root ().html () } } else { return locals } }, 15 ) function postsChart (startMonth ) { const startDate = moment (startMonth || '2020-01' ) const endDate = moment () const monthMap = new Map () const dayTime = 3600 * 24 * 1000 for (let time = startDate; time <= endDate; time += dayTime) { const month = moment (time).format ('YYYY-MM' ) if (!monthMap.has (month)) { monthMap.set (month, 0 ) } } hexo.locals .get ('posts' ).forEach (function (post ) { const month = post.date .format ('YYYY-MM' ) if (monthMap.has (month)) { monthMap.set (month, monthMap.get (month) + 1 ) } }) const monthArr = JSON .stringify ([...monthMap.keys ()]) const monthValueArr = JSON .stringify ([...monthMap.values ()]) return ` <script id="postsChart"> var color = document.documentElement.getAttribute('data-theme') === 'light' ? '#4c4948' : 'rgba(255,255,255,0.7)' var postsChart = echarts.init(document.getElementById('posts-chart'), 'light'); var postsOption = { title: { text: '文章发布统计图', x: 'center', textStyle: { color: color } }, tooltip: { trigger: 'axis' }, xAxis: { name: '日期', type: 'category', boundaryGap: false, nameTextStyle: { color: color }, axisTick: { show: false }, axisLabel: { show: true, color: color }, axisLine: { show: true, lineStyle: { color: color } }, data: ${monthArr} }, yAxis: { name: '文章篇数', type: 'value', nameTextStyle: { color: color }, splitLine: { show: false }, axisTick: { show: false }, axisLabel: { show: true, color: color }, axisLine: { show: true, lineStyle: { color: color } } }, series: [{ name: '文章篇数', type: 'line', smooth: true, lineStyle: { width: 0 }, showSymbol: false, itemStyle: { opacity: 1, color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(128, 255, 165)' }, { offset: 1, color: 'rgba(1, 191, 236)' }]) }, areaStyle: { opacity: 1, color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(128, 255, 165)' }, { offset: 1, color: 'rgba(1, 191, 236)' }]) }, data: ${monthValueArr} , markLine: { data: [{ name: '平均值', type: 'average', label: { color: color } }] } }] }; postsChart.setOption(postsOption); window.addEventListener('resize', () => { postsChart.resize(); }); postsChart.on('click', 'series', (event) => { if (event.componentType === 'series') window.location.href = '/archives/' + event.name.replace('-', '/'); }); </script>` } function tagsChart (len ) { const tagArr = [] hexo.locals .get ('tags' ).map (function (tag ) { tagArr.push ({ name : tag.name , value : tag.length , path : tag.path }) }) tagArr.sort ((a, b ) => { return b.value - a.value }) const dataLength = Math .min (tagArr.length , len) || tagArr.length const tagNameArr = [] for (let i = 0 ; i < dataLength; i++) { tagNameArr.push (tagArr[i].name ) } const tagNameArrJson = JSON .stringify (tagNameArr) const tagArrJson = JSON .stringify (tagArr) return ` <script id="tagsChart"> var color = document.documentElement.getAttribute('data-theme') === 'light' ? '#4c4948' : 'rgba(255,255,255,0.7)' var tagsChart = echarts.init(document.getElementById('tags-chart'), 'light'); var tagsOption = { title: { text: 'Top ${dataLength} 标签统计图', x: 'center', textStyle: { color: color } }, tooltip: {}, xAxis: { name: '标签', type: 'category', nameTextStyle: { color: color }, axisTick: { show: false }, axisLabel: { show: true, color: color, interval: 0 }, axisLine: { show: true, lineStyle: { color: color } }, data: ${tagNameArrJson} }, yAxis: { name: '文章篇数', type: 'value', splitLine: { show: false }, nameTextStyle: { color: color }, axisTick: { show: false }, axisLabel: { show: true, color: color }, axisLine: { show: true, lineStyle: { color: color } } }, series: [{ name: '文章篇数', type: 'bar', data: ${tagArrJson} , itemStyle: { borderRadius: [5, 5, 0, 0], color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(128, 255, 165)' }, { offset: 1, color: 'rgba(1, 191, 236)' }]) }, emphasis: { itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(128, 255, 195)' }, { offset: 1, color: 'rgba(1, 211, 255)' }]) } }, markLine: { data: [{ name: '平均值', type: 'average', label: { color: color } }] } }] }; tagsChart.setOption(tagsOption); window.addEventListener('resize', () => { tagsChart.resize(); }); tagsChart.on('click', 'series', (event) => { if(event.data.path) window.location.href = '/' + event.data.path; }); </script>` } function categoriesChart (dataParent ) { const categoryArr = [] let categoryParentFlag = false hexo.locals .get ('categories' ).map (function (category ) { if (category.parent ) categoryParentFlag = true categoryArr.push ({ name : category.name , value : category.length , path : category.path , id : category._id , parentId : category.parent || '0' }) }) categoryParentFlag = categoryParentFlag && dataParent === 'true' categoryArr.sort ((a, b ) => { return b.value - a.value }) function translateListToTree (data, parent ) { let tree = [] let temp data.forEach ((item, index ) => { if (data[index].parentId == parent) { let obj = data[index]; temp = translateListToTree (data, data[index].id ); if (temp.length > 0 ) { obj.children = temp } if (tree.indexOf ()) tree.push (obj) } }) return tree } const categoryNameJson = JSON .stringify (categoryArr.map (function (category ) { return category.name })) const categoryArrJson = JSON .stringify (categoryArr) const categoryArrParentJson = JSON .stringify (translateListToTree (categoryArr, '0' )) return ` <script id="categoriesChart"> var color = document.documentElement.getAttribute('data-theme') === 'light' ? '#4c4948' : 'rgba(255,255,255,0.7)' var categoriesChart = echarts.init(document.getElementById('categories-chart'), 'light'); var categoryParentFlag = ${categoryParentFlag} var categoriesOption = { title: { text: '文章分类统计图', x: 'center', textStyle: { color: color } }, legend: { top: 'bottom', data: ${categoryNameJson} , textStyle: { color: color } }, tooltip: { trigger: 'item' }, series: [] }; categoriesOption.series.push( categoryParentFlag ? { nodeClick :false, name: '文章篇数', type: 'sunburst', radius: ['15%', '90%'], center: ['50%', '55%'], sort: 'desc', data: ${categoryArrParentJson} , itemStyle: { borderColor: '#fff', borderWidth: 2, emphasis: { focus: 'ancestor', shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(255, 255, 255, 0.5)' } } } : { name: '文章篇数', type: 'pie', radius: [30, 80], roseType: 'area', label: { color: color, formatter: '{b} : {c} ({d}%)' }, data: ${categoryArrJson} , itemStyle: { emphasis: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(255, 255, 255, 0.5)' } } } ) categoriesChart.setOption(categoriesOption); window.addEventListener('resize', () => { categoriesChart.resize(); }); categoriesChart.on('click', 'series', (event) => { if(event.data.path) window.location.href = '/' + event.data.path; }); </script>` }
更多echarts配置项
4.[Blogroot]\source\charts\index.md
添加内容
1 2 3 4 5 6 <!-- 文章发布时间统计图 --> <div id="posts-chart" data-start="2021-01" style="border-radius: 8px; height: 300px; padding: 10px;"></div> <!-- 文章标签统计图 --> <div id="tags-chart" data-length="10" style="border-radius: 8px; height: 300px; padding: 10px;"></div> <!-- 文章分类统计图 --> <div id="categories-chart" data-parent="true" style="border-radius: 8px; height: 300px; padding: 10px;"></div>
5.如果要在标签页、分类页则要修改PUG源码
比如:归档页使用统计图,[Blogroot]\themes\butterfly\layout\archive.pug
1 2 3 4 5 6 extends includes/layout.pug block content include ./includes/mixins/article-sort.pug #archive + <div id="posts-chart" data-start="2021-01" style="height: 300px; padding: 10px;"></div>
pug写法:
1 #posts-chart(data-start="2021-01" style="height: 300px; padding: 10px;")。
博客部署 部署到云服务器
买个服务器(备案)
买个域名(解析、HTTPS、SSL)
Git钩子自动部署
1.安装 git nginx
1 2 3 4 5 6 7 yum -y update yum install -y git nginx 安装完后,rpm -qa | grep nginx 查看 启动nginx:systemctl start nginx 加入开机启动:systemctl enable nginx 查看nginx的状态:systemctl status nginx
2.创建博客目录
1 2 mkdir -p /data/www/blog chmod -R 755 /data/www/blog
3.配置nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 vim /etc/nginx/nginx.conf # vim 查找: /listen 80 # 如果是root用户启动,则设置 # user root server { listen 443 ssl; #填写绑定证书的域名 server_name 域名(xxx.com); #证书文件名称 ssl_certificate 域名(xxx.com)_bundle.crt; #私钥文件名称 ssl_certificate_key 域名(xxx.com).key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; location / { #网站主页路径。此路径仅供参考,具体请您按照实际目录操作。 #例如,您的网站运行目录在/etc/www下,则填写/etc/www。 root /data/www/blog; index index.html index.htm; } } server { listen 80; #填写绑定证书的域名 server_name 域名(xxx.com); #把http的域名请求转成https return 301 https://$host$request_uri; }
4.测试index.html
1 2 3 4 5 6 7 8 9 10 11 12 vim /data/www/blog/index.html <!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"> </head> <body> <p>Nginx running</p> </body> </html>
5.配置git
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 mkdir /data/git_repo chmod -R 755 /data/git_repo > 初始化裸库 cd /data/git_repo git init --bare blog.git > 创建 Git 钩子(hook):用于指定 Git 的源代码 和 Git 配置文件 vim /data/git_repo/blog.git/hooks/post-receive #!/bin/bash git --work-tree=/data/www/blog --git-dir=/data/git_repo/blog.git checkout -f # 指定分支: git --work-tree=/data/www/blog --git-dir=/data/git_repo/public.git checkout main -f > 保存并退出后, 给该文件添加可执行权限 chmod +x /data/git_repo/blog.git/hooks/post-receive
6.本地配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 git --version node -v npm -v npm install hexo-deployer-git # hexo配置文件配置 url: http://www.域名(xxx.com) //个人域名 ...... # 一个是服务器 deploy: type: git repo: root@xx.xx.xx.xx:/data/git_repo/blog.git branch: master # 一键部署 hexo clean && hexo g && hexo d
7.免密登录
1 2 3 4 5 6 7 8 cd ~ mkdir .ssh cd .ssh vi authorized_keys // 这个时候把公钥,也就是windows下的.ssh/id_rsa.pub文件内的文本内容复制粘贴到authorized_keys文件中 chmod 600 ~/.ssh/authorized_keys chmod 700 ~/.ssh
部署到Github
云服务器过期了,续费太贵,想了想还是丢到Github白嫖吧,反正也没什么人看
1.安装插件npm install hexo-deployer-git --save
2.创建Github仓库:(github用户名).github.io
3.站点配置_config.yml
1 2 3 4 5 6 deploy: type: 'git' repo: https://github.com/(github用户名)/(github用户名).github.io.git branch: main
4.部署:hexo clean && hexo g && hexo d
5.github pages 设置 Custom domain
配置 域名
6.不想每次部署后域名都失效,在source目录新增CNAME,将域名填写即可