1 安装NexT v8.0 打开命令行,进入博客根目录,使用git下载NexT 主题
1 2 git clone https://github.com/next-theme/hexo-theme-next themes/next
然后修改博客根目录下的_config.yml
配置文件,将主题设置为NexT
然后重新生成一下博客,打开本地服务
1 2 3 4 5 6 hexo clean hexo generate hexo server --debug
访问http://localhost:4000/ ,查看效果
2 配置修改 2.1 博客配置 以下配置,需添加至博客根目录下_config.yml
中
博客信息 1 2 3 4 5 title: 标题 subtitle: '子标题' description: '描述' keywords: 关键词 author: 作者
开启中文 修改文章永久链接 文章标题大多使用中文,但是URL并不推荐包含中文,也不利于SEO
1 2 url: https://gh1656409967.github.io/ permalink: posts/:hash/
自动检测高亮 1 2 3 highlight: auto_detect: true tab_replace: ' '
显示文章数 1 2 index_generator: per_page: 30
每页页码 默认分类 2.2 主题配置 以下配置,需添加至博客根目录下_config.next.yml
中
切换布局方案 NexT提供Muse
、Mist
、Pisces
和Gemini
四种布局方案。
添加子标题 1 index_with_subtitle: true
关闭页面底部博客信息 格式为Key: /link || icon
,icon即为Font Awesome 提供的图标。 修改主题目录下languages/zh-CN.yml
,在menu下添加对应菜单的中文,例如gallery: 相册
,注意统一缩进。 在博客根目录,运行 hexo new page "菜单"
,编辑新建的 source/菜单/index.md
即可。 1 2 3 menu: about: /about/ || fa fa-user gallery: /gallery/ || fa fa-camera
添加社交链接 1 2 3 4 5 social: GitHub: https://github.com/GH1656409967 || fa-brands fa-github QQ: http://wpa.qq.com/msgrd?v=3&uin=1656409967&site=qq&menu=yes || fa-brands fa-qq 网易云: https://music.163.com/#/user/home?id=270121274 || fa fa-music 豆瓣: https://www.douban.com/people/215985894/ || fa fa-video-camera
添加友链 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 links_settings: icon: fa fa-link title: 友情链接 layout: inline links: 【jaihk662】: https://blog.csdn.net/jaihk662 【信仰.】: https://blog.csdn.net/haut_ykc 【SSimpLe_Y】: https://blog.csdn.net/ssimple_y 【柳婼のblog】: https://www.liuchuo.net/ 【liweihang】: https://www.cnblogs.com/liweihang/ 【ironz】: https://ironz.cn/ 【Sysipus】: https://runzhaochen.github.io/ 【Long_hen】: https://blog.csdn.net/Long_hen 【haut_bao】: https://blog.csdn.net/qq_41856950 【阿清そ 】: https://aqingya.cn/
目录设置 开启目录,关闭目录自动编号,开启目录自动换行,开启全部展开
1 2 3 4 5 toc: enable: true number: false wrap: true expand_all: true
开启文章结尾版权声明 1 2 creative_commons: post: true
文章结尾打赏 添加文章结尾打赏图片,图片放至主题目录的source/images/
下
1 2 3 4 5 6 7 8 reward_settings: enable: true animation: false reward: wechatpay: /images/wechatpay.png alipay: /images/thanks.png bitcoin: /images/alipay.png
修改themes/next/languages/zh-CN.yml
,文字与图片对应
1 2 3 4 reward: wechatpay: 微信 alipay: 感谢 bitcoin: 支付宝
网站头像 图片放至主题目录的source/images/
下
1 2 avatar: url: /images/avatar.png
网站图标 图片放至主题目录的source/images/
下
1 2 3 favicon: small: /images/favicon-16x16-.png medium: /images/favicon-32x32-.png
设置字体 设置字体为Fira Code和思源黑体
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 font: enable: true host: global: external: true family: 'Fira Code,Noto Sans SC' size: title: external: true family: 'Fira Code,Noto Sans SC' size: headings: external: true family: 'Fira Code,Noto Sans SC' size: posts: external: true family: 'Fira Code,Noto Sans SC' codes: external: true family: 'Fira Code,Noto Sans SC'
设置代码高亮 1 2 3 codeblock: theme: light: atom-one-light
代码一键复制 1 2 3 4 codeblock: copy_button: enable: true show_result: true
切换CDN jsdelivr容易寄,可以换cdnjs或者unpkg
1 2 vendors: plugins: unpkg
3 功能添加 3.1 图片不显示 此处仅处理本地图片引用,不考虑使用图床的情况
从之前生成的静态文件中,可以看到图片未上传至public
目录,且图片路径是markdown源文件中的绝对路径,而不是相对路径。
首先修改博客根目录_config.yml
配置文件,开启上传资源文件夹
然后需要安装一个图片路径转换插件,打开命令行,进入博客根目录,执行以下命令
1 npm i hexo-asset-image --save
图片路径转换插件 修改此插件源码/node_modules/hexo-asset-image/index.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 ... if (config.post_asset_folder ){ var link = data.permalink ; var beginPos = getPosition (link, '/' , 3 ) + 1 ; var endPos = link.lastIndexOf ('/' ) + 1 ; link = link.substring (beginPos, endPos); var toprocess = ['excerpt' , 'more' , 'content' ]; ... $('img' ).each (function ( ){ if ($(this ).attr ('data-src' )){ var src = $(this ).attr ('data-src' ).replace ('\\' , '/' ); if (!(/http[s]*.*|\/\/.*/ .test (src) || /^\s+\// .test (src) || /^\s*\/uploads|images\// .test (src))) { ... $(this ).attr ('data-src' , config.root + link + src); console .info &&console .info ("update link as:-->" +config.root + link + src); } ...
清除缓存,重新生成博客,打开本地服务,查看效果
3.2 MathJax 使用MathJax ,开启LaTeX 数学公式支持。首先更换解析器,打开命令行,进入博客根目录,执行以下命令
1 2 3 4 npm uninstall hexo-renderer-marked --save npm install hexo-renderer-pandoc --save
更换解析器 然后安装Pandoc ,并且配置好环境变量。在博客根目录_config.next.yaml
中添加
1 2 3 math: mathjax: enable: true
使用时需要在文章的front-matter里打开mathjax: true
,简单测试
1 $ $ x = {-b \pm \sqrt {b^ 2-4ac} \over 2a} $ $
\[ x = {-b \pm \sqrt{b^2-4ac} \over 2a} \]
1 $ $ f(a) = \frac {1}{2\pi i} \oint \frac {f(z)}{z-a}dz $ $
\[ f(a) = \frac{1}{2\pi i} \oint\frac{f(z)}{z-a}dz \]
1 $ $ \cos (\theta +\phi )=\cos (\theta )\cos (\phi )−\sin (\theta )\sin (\phi ) $ $
\[ \cos(\theta+\phi)=\cos(\theta)\cos(\phi)−\sin(\theta)\sin(\phi) \]
1 $ $ \int _ D ({\nabla \cdot } F)dV=\int _ {\partial D} F\cdot ndS $ $
\[ \int_D ({\nabla\cdot} F)dV=\int_{\partial D} F\cdot ndS \]
1 2 3 4 5 6 $ $ \vec {\nabla } \times \vec {F} = \left ( \frac {\partial F_ z}{\partial y} - \frac {\partial F_ y}{\partial z} \right ) \mathbf {i} + \left ( \frac {\partial F_ x}{\partial z} - \frac {\partial F_ z}{\partial x} \right ) \mathbf {j} + \left ( \frac {\partial F_ y}{\partial x} - \frac {\partial F_ x}{\partial y} \right ) \mathbf {k} $ $
\[ \vec{\nabla} \times \vec{F} = \left( \frac{\partial F_z}{\partial y} - \frac{\partial F_y}{\partial z} \right) \mathbf{i} + \left( \frac{\partial F_x}{\partial z} - \frac{\partial F_z}{\partial x} \right) \mathbf{j} + \left( \frac{\partial F_y}{\partial x} - \frac{\partial F_x}{\partial y} \right) \mathbf{k} \]
1 $ $ \sigma = \sqrt { \frac {1}{N} \sum _ {i=1}^ N (x_ i -\mu )^ 2} $ $
\[ \sigma = \sqrt{ \frac{1}{N} \sum_{i=1}^N (x_i -\mu)^2} \]
1 2 3 4 $ $ (\nabla _ X Y)^ k = X^ i (\nabla _ i Y)^ k = X^ i \left ( \frac {\partial Y^ k}{\partial x^ i} + \Gamma _ {im}^ k Y^ m \right ) $ $
\[ (\nabla_X Y)^k = X^i (\nabla_i Y)^k = X^i \left( \frac{\partial Y^k}{\partial x^i} + \Gamma_{im}^k Y^m \right) \]
3.3 搜索功能 安装搜索插件
1 npm i hexo-generator-searchdb --save
打开 _config.next.yml
,添加
1 2 local_search: enable: true
打开hexo的站点配置 _config.yml
,添加
1 2 3 4 5 search: path: search.json field: post format: html limit: 10000
3.4 统计功能 显示文章字数统计、阅读时长及总字数。首先安装插件
1 npm i hexo-word-counter --save
Hexo统计插件 修改博客根目录_config.yml
配置
1 2 3 4 5 6 7 8 9 symbols_count_time: symbols: true time: true total_symbols: true total_time: true exclude_codeblock: true awl: 2 wpm: 300 suffix: "分钟"
修改博客根目录_config.next.yml
主题配置
1 2 3 symbols_count_time: separated_meta: false item_text_total: true
3.5 简易相册 得益于Markdown和HTML混编可以被部分解析器解析的优势,可以使用HTML+CSS,添加一个简易相册。
注意:之前由于为了使用MathJax而更换解析器为Pandoc,对于需要解析raw-html的文章,所有标签前不应有空格,且块级标签前后需要留出空行
首先hexo n page gallery
,创建图库。修改图库页面gallery/index.md
,按照以下格式添加相册,相册封面图片放至gallery/index/
目录下。
1 2 3 4 5 6 7 8 9 10 11 12 <div class ="gallery-list" > <div class ="gallery-item" > <a href ="相册1/" > <img data-src ="gallery/index/相册1封面.jpg" > </a > <p > -相册1-</p > </div > <div class ="gallery-item" > <a href ="相册2/" > <img data-src ="gallery/index/相册2封面.jpg" > </a > <p > -相册2-</p > </div > </div >
新建相册页面gallery/相册名/index.md
,按照以下格式添加图片,图片放至gallery/相册名/index/
目录下,其它相册同理。
1 2 3 4 5 6 7 8 9 10 <div class ="img-list" > <div class ="img-item" > <img data-src ="相册1/index/图片1.png" alt ="图片1标题" > </div > <div class ="img-item" > <img data-src ="相册1/index/图片2.jpg" alt ="图片2标题" > </div > <div class ="img-item" > <img data-src ="相册1/index/图片3.png" alt ="图片3标题" > </div > <div class ="img-item" > <img data-src ="相册1/index/图片4.png" alt ="图片4标题" > </div > <div class ="img-item" > <img data-src ="相册1/index/图片5.jpg" alt ="图片5标题" > </div > <div class ="img-item" > <img data-src ="相册1/index/图片6.png" alt ="图片6标题" > </div > </div >
在博客根目录下 _config.next.yml
中添加
1 2 menu: gallery: /gallery/ || fa fa-camera
在主题目录下,修改国际化文件languages\zh-CN.yml
,添加
在博客根目录下,新建source/_data/styles.styl
,添加自定义样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 .img-list , .gallery-list { gap : 1rem ; grid-gap : 1rem ; display : grid; grid-template-columns : repeat(auto-fit, minmax(250px , 1 fr)); padding : 1rem ; align-items : center; align-content : center; justify-items: center; justify-content : center; } .img-item img , .gallery-item img { width : 250px ; height : 200px ; object-fit : cover; border : 1px solid rgba(221 , 221 , 221 , 0.5 ); border-radius : 7px ; margin-top : 10px ; margin-left : 5px ; margin-right : 5px ; } .gallery-item p { margin : 0 auto; max-width : 50% ; border : 1px solid $black -deep; border-radius : 7px ; background : rgba(255 , 255 , 255 , 0.3 ); box-shadow : 0 8px 20px -8px rgba(0 , 0 , 0 , 0.3 ); color : $black -deep; text-align : center; font-size : 15px ; } @media (max-width : 767px ) { .gallery-item p { min-width : 75px ; font-size : 13px ; } }
修改博客根目录下_config.next.yml
,引用自定义样式
1 2 custom_file_path: style: source/_data/styles.styl
3.6 添加分类和标签 打开命令行,进入博客根目录,执行以下命令
1 2 3 4 hexo n page categories hexo n page tags
修改source/categories/index.md
,在front-matter中添加
1 2 3 4 5 --- title: 分类 date: 2022-04-22 16:47:13 type: "categories" ---
修改source/tags/index.md
,在front-matter中添加
1 2 3 4 5 --- title: 标签 date: 2022-04-22 16:47:30 type: "tags" ---
3.7 代码折叠 强推hexo博客代码折叠功能
在主题目录下,添加source/js/code-unfold.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 var CODE_MAX_HEIGHT = 250 ;var containers = [];$('body' ).on ('click' , '.js_unfold_code_btn' , function ( ) { $(this ).closest ('.js_highlight_container' ).addClass ('on' ); }); $('body' ).on ('click' , '.js_retract_code_btn' , function ( ) { var $container = $(this ).closest ('.js_highlight_container' ).removeClass ('on' ); var winTop = $(window ).scrollTop (); var offsetTop = $container.offset ().top ; $(this ).css ('top' , 0 ); if (winTop > offsetTop) { $('body, html' ).animate ({ scrollTop : $container.offset ().top - CODE_MAX_HEIGHT }, 600 ); } }); $(window ).on ('scroll' , function ( ) { var scrollTop = $(window ).scrollTop (); var temp = []; for (let i = 0 ; i < containers.length ; i++) { var item = containers[i]; var { $container, height, $hide, hasHorizontalScrollbar } = item; if ($container.closest ('body' ).length === 0 ) { continue ; } temp.push (item); if (!$container.hasClass ('on' )) { continue ; } var offsetTop = $container.offset ().top ; var hideBtnHeight = $hide.outerHeight (); var maxTop = parseInt (height - (hasHorizontalScrollbar ? 17 : 0 ) - hideBtnHeight); let top = parseInt ( Math .min ( Math .max (scrollTop - offsetTop, 0 ), maxTop, ) ); var halfHeight = parseInt ($(window ).height () / 2 * Math .sin ((top / maxTop) * 90 * (2 * Math .PI / 360 ))); $hide.css ('top' , Math .min (top + halfHeight, maxTop)); } containers = temp; }); function addCodeWrap ($node ) { var $container = $node.wrap ('<div class="js_highlight_container highlight-container"><div class="highlight-wrap"></div></div>' ).closest ('.js_highlight_container' ); var $btn = $(` <div class="highlight-footer"> <a class="js_unfold_code_btn show-btn" href="javascript:;">展开代码<i class="fa fa-angle-down" aria-hidden="true"></i></a> </div> <a class="js_retract_code_btn hide-btn" href="javascript:;"><i class="fa fa-angle-up" aria-hidden="true"></i>收起代码</a> ` ); $container.append ($btn); return $container; }; function codeUnfold ( ) { $('.highlight' ).each (function ( ) { if (this .__render__ === true ) { return true ; } this .__render__ = true ; var $this = $(this ); var height = $(this ).outerHeight (); if (height > CODE_MAX_HEIGHT ) { var $container = addCodeWrap ($this, height); containers.push ({ $container, height, $hide : $container.find ('.js_retract_code_btn' ), hasHorizontalScrollbar : this .scrollWidth > this .offsetWidth , }); } }); };
在NexT主题中全局引用jQuery,或者在_config.next.yml
中开启Fancybox,Fancybox会依赖jQuery,
引用code-unfold.js
,在主题目录下,layout/_scripts/index.njk
的最后添加
1 {{- next_js('code-unfold.js') }}
修改主题目录下source/js/next-boot.js
1 2 3 4 NexT .boot .refresh = function ( ) { codeUnfold ();
打开之前创建的source/_data/styles.styl
,添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 .highlight-container { position : relative; background-color : highlight-background; &.on { .highlight-footer { display : none; } .hide-btn { display : flex; } .highlight-wrap { max-height : none; } } .highlight-wrap { overflow : hidden; max-height : 200px ; } .highlight-footer { position : absolute; bottom : 0 ; left : 0 ; width : 100% ; height : 60px ; background-image : 'linear-gradient(-180deg, rgba(255,255,255,0) 0%, %s 65%)' % highlight-background; text-align : center; } .show-btn { position : absolute; bottom : 0 ; left : 50% ; padding : 0 0.8em ; border-radius : 4px 4px 0 ; color : #fff ; text-align : center; text-decoration : none; font-size : 12px ; line-height : 2em ; transform : translateX(-50% ); &:hover { text-decoration : none; } } .hide-btn { position : absolute; top : 0 ; left : -21px ; display : none; flex-direction : column; padding : 0.1em 0 0.6em ; width : 22px ; border-radius : 4px 0 0 4px ; background-color : highlight-background; color : #fff ; text-align : center; text-decoration : none; font-size : 12px ; line-height : 1em ; transition : top ease 0.35s ; } .fa-angle-up , .fa-angle-down { color : #fff ; font-style : normal; } .fa-angle-up :before { content : '\f106' ; } .fa-angle-down :before { margin-left : 0.5em ; content : '\f107' ; } .js_unfold_code_btn , .js_retract_code_btn { border-bottom : none !important ; background : rgba(0 , 0 , 0 , 0.5 ); &:hover { border-bottom-color : none !important ; } } }
3.8 折叠内容 推荐Hexo 静态博客添加可折叠内容
在主题目录下创建scripts/tags/fold_tag.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function fold (args, content ) { var text = args[0 ]; if (!text) text = "点击显示/隐藏" ; return '<div><div class="fold_hider"><div class="close hider_title">' + hexo.render .renderSync ({ text : text, engine : 'markdown' }).replace (/^<p>/ , '' ).replace (/<\/p>$/ , '' ) + '</div></div><div class="fold">\n' + hexo.render .renderSync ({ text : content, engine : 'markdown' }) + '\n</div></div>' ; } hexo.extend .tag .register ('fold' , fold, { ends : true });
在主题目录下创建source/js/fold_action.js
1 2 3 4 5 6 7 8 $(document ).ready (function ( ) { $(document ).on ('click' , '.fold_hider' , function ( ) { $('>.fold' , this .parentNode ).slideToggle (); $('>:first' , this ).toggleClass ('open' ); }); $("div.fold" ).css ("display" , "none" ); });
打开之前创建的source/_data/styles.styl
,添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 .hider_title { cursor : pointer; background : #eeeeee ; } .close :before { padding-left : 0.5em ; padding-right : 0.5em ; content : '▼' ; } .open :before { padding-left : 0.5em ; padding-right : 0.5em ; content : '▲' ; } p code , .hider_title code { color : #c71585 ; background : #fffafa ; margin : 2px ; }
在博客根目录_config.next.yml
中添加
1 2 custom_file_path: bodyEnd: source/_data/body-end.njk
在博客根目录下创建source/_data/body-end.njk
1 2 {# 代码折叠 #} <script type="text/javascript" src="/js/fold_action.js"></script>
使用fold
标签,可以折叠内容
1 2 3 {% fold 折叠内容 %} Hello World {% endfold %}
注意:如果开启了pjax
,则需要修改主题目录下source/js/next-boot.js
1 2 3 4 NexT .boot .refresh = function ( ) { $("div.fold" ).css ("display" , "none" );
3.9 压缩 添加官方插件hexo-clean-css
、hexo-html-minifier
和hexo-uglify
1 npm i hexo-clean-css hexo-html-minifier hexo-uglify --save
Hexo压缩插件 在博客根目录_config.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 uglify: mangle: true exclude: - '*.min.js' es6: false clean_css: exclude: - '*.min.css' html_minifier: collapseBooleanAttributes: true collapseWhitespace: true ignoreCustomComments: [ !!js/regexp /^\s*more/ ] removeComments: true removeEmptyAttributes: true removeScriptTypeAttributes: true removeStyleLinkTypeAttributes: true minifyJS: true minifyCSS: true
3.10 评论系统 Gitalk是一个基于GitHub Issue和Preact开发的评论插件。
首先需要去GitHub 新建一个仓库,点击New
创建
GitHub创建仓库 然后创建GitHub Application
GitHub创建应用 然后点击Generate a new client secret
,验证GitHub密码后,保存好Client ID
和Client secrets
GitHub保存信息 在博客根目录下_config.next.yml
中添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 comments: style: buttons active: gitalk storage: true lazyload: true nav: gitalk: order: -2 gitalk: enable: true github_id: gh1656409967 repo: Gitalk client_id: adfg89av4s9bf4s89nsn client_secret: 1561aefeaegadadag5e1a68bbfsnyfsrg4587sr7 admin_user: gh1656409967 distraction_free_mode: true proxy: https://cors-anywhere.azm.workers.dev/https://github.com/login/oauth/access_token language: zh-CN
然后每次新生成文章/页面后,都需要去文章页初始化Issues
初始化Issues 点击使用GitHub登录
后,再点击Authorize username
GitHub验证信息 刷新后即可开启评论
Gitalk评论 3.11 博文加密 首先打开命令行,进入博客根目录,执行以下命令,安装hexo-blog-encrypt
插件
1 npm install hexo-blog-encrypt --save
在需要加密的文章开头front-matter中添加
1 2 3 4 password: 123456 abstract: 博文被加密了, 请输入密码查看。 message: 您好, 这里需要密码。 wrong_pass_ message: 抱歉, 这个密码看着不太对, 请再试试。
注意,Fancybox可能会不加载,复制themes\next\source\js\third-party\fancybox.js
的内容,添加到node_modules\hexo-blog-encrypt\lib\hbe.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 ... function refreshfancybox ( ) { document .querySelectorAll ('.post-body :not(a) > img, .post-body > img' ).forEach (element => { const $image = $(element); const imageLink = $image.attr ('data-src' ) || $image.attr ('src' ); const $imageWrapLink = $image.wrap (`<a class="fancybox fancybox.image" href="${imageLink} " itemscope itemtype="http://schema.org/ImageObject" itemprop="url"></a>` ).parent ('a' ); if ($image.is ('.post-gallery img' )) { $imageWrapLink.attr ('data-fancybox' , 'gallery' ).attr ('rel' , 'gallery' ); } else if ($image.is ('.group-picture img' )) { $imageWrapLink.attr ('data-fancybox' , 'group' ).attr ('rel' , 'group' ); } else { $imageWrapLink.attr ('data-fancybox' , 'default' ).attr ('rel' , 'default' ); } const imageTitle = $image.attr ('title' ) || $image.attr ('alt' ); if (imageTitle) { if (!$imageWrapLink.next ('figcaption' ).length ) { $imageWrapLink.append (`<p class="image-caption">${imageTitle} </p>` ); } $imageWrapLink.attr ('title' , imageTitle).attr ('data-caption' , imageTitle); } }); $.fancybox.defaults .hash = false ; $('.fancybox' ).fancybox ({ loop : true , helpers : { overlay : { locked : false } } }); } async function decrypt (decryptKey, iv, hmacKey ) { let typedArray = hexToArray (encryptedData); const result = await cryptoObj.subtle .decrypt ({ 'name' : 'AES-CBC' , 'iv' : iv, }, decryptKey, typedArray.buffer ).then (async (result) => { ... refreshfancybox (); return await verifyContent (hmacKey, decoded); }).catch ((e ) => { alert (wrongPassMessage); console .log (e); return false ; }); ...
3.11 aplayer音乐播放器 首先打开命令行,进入博客根目录,执行以下命令,安装aplayer
插件
1 npm install aplayer --save
在source/_data/body-end.njk
添加以下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/aplayer/1.10.1/APlayer.min.css" integrity="sha512-CIYsJUa3pr1eoXlZFroEI0mq0UIMUqNouNinjpCkSWo3Bx5NRlQ0OuC6DtEB/bDqUWnzXc1gs2X/g52l36N5iw==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/aplayer/1.10.1/APlayer.min.js" integrity="sha512-RWosNnDNw8FxHibJqdFRySIswOUgYhFxnmYO3fp+BgCU7gfo4z0oS7mYFBvaa8qu+axY39BmQOrhW3Tp70XbaQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <div id="aplayer"></div> <script> const ap = new APlayer({ container: document.getElementById('aplayer'), fixed: true, listFolded: true, lrcType: 3, audio: [ { name: 'AVICII UMF2016 Live', artist: 'Avicii', url: 'https://music.163.com/song/media/outer/url?id=440767926.mp3', cover: 'http://p2.music.126.net/kmo__VMOex_fRScv2RXStA==/109951162842392590.jpg', lrc: '/lyric/AVICII UMF2016 Live.lrc' }, { ... }, ] }); </script>
其中,APlayer.min.js
和APlayer.min.css
可以使用CDN ,也可以在GitHub 上下载。配置内容的具体含义参考APlayer官方文档 。
url后面填写歌曲外链。打开网页版网易云音乐,选择非VIP歌曲,点开至歌词页面,将地址栏中的歌曲id,复制到https://music.163.com/song/media/outer/url?id=xxxx.mp3
对应位置。
网易云外链 cover后面填写封面图片链接。以edge为例,按F12
进入控制台,使用选择元素,选中封面,在对应的img
标签内复制data-src
属性的值。
网易云封面图片 lrc后面填写本地保存的歌词文件。以edge为例,按F12
进入控制台,选择网络,搜索lyric
,然后刷新歌词页面,找到对应的歌词文件,lrc
对应外文歌词,tlyric
对应翻译歌词,将lyric
后面的值复制到的本地文件中,以.lrc
格式保存,然后引用即可。我这里保存在主题目录下source/lyric/
中。
网易云歌词 注意:链接跳转后播放会被打断,使用pjax可以解决这个问题。
3.12 豆瓣插件 注意:此方法适合像我这样的懒人,由于hexo升级至6.1.0后,不再使用ejs等,建议能折腾的好好重写这个插件。
首先打开命令行,进入博客根目录,执行以下命令,安装hexo-douban
豆瓣插件
1 npm install hexo-douban --save
在博客根目录_config.yml
中添加
1 2 3 4 5 6 7 8 9 10 douban: user: lordash builtin: false book: title: 'This is my book title' quote: 'This is my book quote' movie: title: 'This is my movie title' quote: 'This is my movie quote' timeout: 10000
user
豆瓣用户名,登录豆瓣,点击个人主页,地址栏URL中https://www.douban.com/people/xxxxxx/ 后的xxxxxx即是个人ID。title
页面标题,builtin
是否将生成页面功能嵌入hexo g
中,默认为false,quote
是页面开头的一段话,timeout
是豆瓣接口超时时间,默认为10000毫秒,如果在使用时发现报了超时的错(ETIMEOUT)可以把这个数据设置的大一点。
然后修改_config.next.yml
,添加
1 2 3 menu: books: /books/ || fa fa-book movies: /movies/ || fa fa-film
修改themes\next\languages\zh-CN.yml
,添加
1 2 3 menu: books: 书籍 movies: 影音
使用hexo douban
生成豆瓣页面,命令行提示
1 2 INFO 0 books have been loaded in 858 ms, because you are offline or your network is bad INFO 0 movies have been loaded in 1751 ms, because you are offline or your network is bad
根据打印,在node_modules\hexo-douban\lib\books-generator.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 ... var offline = false ;# 添加hexo-log引用 var log = require ('hexo-log' )({ debug : false , silent : false }); var log = require ('hexo-log' )({ debug : false , silent : false }); function resolv (url, timeout, headers ) { var response = '' ; try { response = request (url, { timeout : timeout, dataType : 'xml' , headers : headers, }); } catch (err) { # 打印详细错误日志 log.error (err); offline = true ; } ...
再次hexo douban
生成,可以看到详细错误提示,
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 ERROR E:\work\blog\node_modules\urllib-sync\request.js:44 var filepath = path.join(os.tmpDir(), name); ^ TypeError: os.tmpDir is not a function at E:\work\blog\node_modules\urllib-sync\request.js:44:31 at done (E:\work\blog\node_modules\urllib\lib\urllib.js:396:5) at E:\work\blog\node_modules\urllib\lib\urllib.js:628:9 at decodeContent (E:\work\blog\node_modules\urllib\lib\urllib.js:469:14) at IncomingMessage.<anonymous> (E:\work\blog\node_modules\urllib\lib\urllib.js:593:7) at IncomingMessage.emit (node:events:538:35) at endReadableNT (node:internal/streams/readable:1345:12) at processTicksAndRejections (node:internal/process/task_queues:83:21) Error: E:\work\blog\node_modules\urllib-sync\request.js:44 var filepath = path.join(os.tmpDir(), name); ^ TypeError: os.tmpDir is not a function at E:\work\blog\node_modules\urllib-sync\request.js:44:31 at done (E:\work\blog\node_modules\urllib\lib\urllib.js:396:5) at E:\work\blog\node_modules\urllib\lib\urllib.js:628:9 at decodeContent (E:\work\blog\node_modules\urllib\lib\urllib.js:469:14) at IncomingMessage.<anonymous> (E:\work\blog\node_modules\urllib\lib\urllib.js:593:7) at IncomingMessage.emit (node:events:538:35) at endReadableNT (node:internal/streams/readable:1345:12) at processTicksAndRejections (node:internal/process/task_queues:83:21) at request (E:\work\blog\node_modules\urllib-sync\index.js:44:13) at resolv (E:\work\blog\node_modules\hexo-douban\lib\books-generator.js:25:20) at Hexo.module.exports (E:\work\blog\node_modules\hexo-douban\lib\books-generator.js:134:23) at Hexo.tryCatcher (E:\work\blog\node_modules\bluebird\js\release\util.js:16:23) at Hexo.<anonymous> (E:\work\blog\node_modules\bluebird\js\release\method.js:15:34) at E:\work\blog\node_modules\hexo\lib\hexo\index.js:407:22 at tryCatcher (E:\work\blog\node_modules\bluebird\js\release\util.js:16:23) at MappingPromiseArray._promiseFulfilled (E:\work\blog\node_modules\bluebird\js\release\map.js:68:38) at MappingPromiseArray.PromiseArray._iterate (E:\work\blog\node_modules\bluebird\js\release\promise_array.js:115:31) at MappingPromiseArray.init (E:\work\blog\node_modules\bluebird\js\release\promise_array.js:79:10) at MappingPromiseArray._asyncInit (E:\work\blog\node_modules\bluebird\js\release\map.js:37:10) at _drainQueueStep (E:\work\blog\node_modules\bluebird\js\release\async.js:97:12) at _drainQueue (E:\work\blog\node_modules\bluebird\js\release\async.js:86:9) at Async._drainQueues (E:\work\blog\node_modules\bluebird\js\release\async.js:102:5) at Immediate.Async.drainQueues [as _onImmediate] (E:\work\blog\node_modules\bluebird\js\release\async.js:15:14) at processImmediate (node:internal/timers:466:21)
看来是由于Node.js
升级后,os.tmpDir()
方法失效导致。我们使用os.tmpdir()
替换node_modules\urllib-sync\request.js
中的os.tmpDir()
,再次使用hexo douban
后,生成成功。
使用pjax
,还需要修改node_modules\hexo-douban\lib\templates\book.ejs
,
1 2 3 4 5 /* 添加data-pjax属性 */ <script data-pjax> <% include index.js %> <% include pagination.js %> </script>