几百年前刚建立这个博客时几乎什么都不懂,胡乱作一气。尽管包管理稀烂,Bug 层出不穷,部署时一堆报错…… 但索性能运行起来。
最近把整个仓库推到 Github 做持续集成,数据也不那么容易遗失。刚开始看没问题,结果主题调用的资源全部变成相对路径了,一片报错。
剪不断,理还乱…… 烂摊不好收,就重新建一个!
安装 Hexo
什么?您若想了解安装流程,还请移步至 Hexo 官网。
版本:
Shell1 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
| ❯ nvm -v 1.1.10
❯ node -v v12.22.12
❯ hexo version hexo: 6.3.0 hexo-cli: 4.3.1 os: win32 10.0.22631 node: 12.22.12 v8: 7.8.279.23-node.57 uv: 1.40.0 zlib: 1.2.11 brotli: 1.0.9 ares: 1.18.1 modules: 72 nghttp2: 1.41.0 napi: 8 llhttp: 2.1.4 http_parser: 2.9.4 openssl: 1.1.1n cldr: 37.0 icu: 67.1 tz: 2021a4 unicode: 13.0
|
更换渲染引擎
默认孬。即换,以免兼容问题。
hexo-renderer-markdown-it
卸载:
Shell1 2
| ❯ npm un hexo-renderer-marked --save 好嘛,卸载 hexo-renderer-marked 中……
|
安装:
Shell1 2
| ❯ npm i hexo-renderer-markdown-it --save 好嘛,安装 hexo-renderer-markdown-it 中……
|
配置:
_config.yml1 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
| + # 以下是扩展设置 + + ## hexo-renderer-markdown-it https://github.com/hexojs/hexo-renderer-markdown-it + markdown: + preset: 'default' + render: + html: true # 启用页内 HTML + xhtmlOut: false # 是否完全兼容 XHTML + langPrefix: 'language-' + breaks: false # 换行变 <br> + linkify: false # 长得像链接的变 <a> + typographer: true # 能够替换常见的排版元素,如©、卷曲引号、破折号等 + quotes: '“”‘’' + enable_rules: + disable_rules: + plugins: + - markdown-it-container + - markdown-it-footnote + - markdown-it-ins + anchors: + level: 2 + collisionSuffix: '' + permalink: false + permalinkClass: 'header-anchor' + permalinkSide: 'left' + permalinkSymbol: '¶' + case: 0 + separator: '-' + images: + lazyload: false + prepend_root: false + post_asset: false + inline: false # https://markdown-it.github.io/markdown-it/#MarkdownIt.renderInline
|
安装并启用 Icarus 主题
Shell1 2
| ❯ npm install hexo-theme-icarus 好嘛,安装 hexo-theme-icarus 中……
|
_config.yml1 2 3 4 5
| # Extensions ## Plugins: https://hexo.io/plugins/ ## Themes: https://hexo.io/themes/ - theme: landscape + theme: icarus
|
设置评论系统
本文撰写时 Icarus 主题不支持 giscus 评论系统。只好手动添加到源码。
先随便设置,让界面不报错:
_config.icarus.yml1 2 3 4 5 6 7 8 9
| # Comment plugin configurations # https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Comment/ comment: - type: disqus - # Disqus shortname - shortname: '' + type: utterances # 实际上我已经把 giscus 代码覆盖到 node_modules/hexo-theme-icarus/layout/common/comment.jsx + repo: Username/Username.github.io + issue_term: title
|
覆盖前备份:
Shell1
| ❯ cp node_modules/hexo-theme-icarus/layout/common/comment.jsx node_modules/hexo-theme-icarus/layout/common/comment.jsx node_modules/hexo-theme-icarus/layout/common/comment.jsx node_modules/hexo-theme-icarus/layout/common/comment.jsx.bak
|
在 giscus 官网设置好的配置覆盖到 node_modules/hexo-theme-icarus/layout/common/comment.jsx
:
node_modules/hexo-theme-icarus/layout/common/comment.jsx1 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
| return <div class="card"> <div class="card-content"> <h3 class="title is-5">{__('article.comments')}</h3> + <script src="https://giscus.app/client.js" + data-repo="Username/Username.github.io" + data-repo-id="XXxXXXXxXXXx" + data-category="Announcements" + data-category-id="XXX_xxXXxXXXxxXXXX" + data-mapping="title" + data-strict="1" + data-reactions-enabled="1" + data-emit-metadata="0" + data-input-position="top" + data-theme="light_tritanopia" + data-lang="zh-CN" + crossorigin="anonymous" + async> + </script> - {(() => { - try { - let Comment = view.require('comment/' + comment.type); - Comment = Comment.Cacheable ? Comment.Cacheable : Comment; - return <Comment config={config} page={page} helper={helper} comment={comment} />; - } catch (e) { - logger.w(`Icarus cannot load comment "${comment.type}"`); - return null; - } - })()} + {/* {(() => { + try { + let Comment = view.require('comment/' + comment.type); + Comment = Comment.Cacheable ? Comment.Cacheable : Comment; + return <Comment config={config} page={page} helper={helper} comment={comment} />; + } catch (e) { + logger.w(`Icarus cannot load comment "${comment.type}"`); + return null; + } + })()} */} </div> </div>;
|
hexo-generator-feed
安装:
Shell1 2 3 4
| ❯ npm install hexo-generator-feed --save
+ hexo-generator-feed@3.0.0 added 1 package from 1 contributor in 2.848s
|
配置:
_config.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| + ## hexo-generator-feed + feed: + enable: true + # type: atom + # path: atom.xml + type: + - atom + - rss2 + path: + - atom.xml + - rss2.xml + limit: 20 + hub: + content: + content_limit: 140 + content_limit_delim: ' ' + order_by: -date + icon: /images/PJ568.svg + autodiscovery: true + template:
|
嗯。好。
配置自动翻译
不想为国际化而重写文章。因此,我集成 translate.js 。
规划
顶栏右侧生成 “翻译” 按钮。按下展开菜单以选择语言。
问题在于 translate.js 生成的是 <select>
元素。难以做到按下按钮打开 <select>
元素。
我可以将 <select>
元素设定成透明,用 z-index
使它覆盖在 “翻译” 按钮上层,这样点击按钮位置实际上点到的是 <select>
元素。(哈,我聪明)
调整样式
创建并写入:
source/css/translate.css1
| + .translateSelectLanguage{z-index:10;width:100%;height:100%;opacity:0;cursor:pointer;position:absolute;left:0}
|
设置翻译
创建并写入:
source/js/translate_lib.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| + function initTranslate() { + try{ + translate.service.use('client.edge'); + translate.listener.start(); + // translate.language.setLocal('chinese_simplified'); + translate.setAutoDiscriminateLocalLanguage(); + translate.language.setUrlParamControl(); + translate.ignore.class.push('notTranslate'); + translate.nomenclature.append('chinese_simplified','english',` + 刘甜=Liu Tian + `); + translate.execute(); + } + catch(e){console.log('翻译系统出错:' + e);} + } + + window.addEventListener('load', initTranslate);
|
插入代码
不翻译页标题
确保标题不被翻译(我设置的 giscus 依赖):
先备份:
Shell1
| ❯ cp node_modules/hexo-theme-icarus/layout/common/head.jsx node_modules/hexo-theme-icarus/layout/common/navbar.jsx node_modules/hexo-theme-icarus/layout/common/comment.jsx node_modules/hexo-theme-icarus/layout/common/head.jsx.bak
|
插入代码:
node_modules/hexo-theme-icarus/layout/common/head.jsx1 2
| - <title>{getPageTitle(page, config.title, helper)}</title> + <title class="notTranslate">{getPageTitle(page, config.title, helper)}</title>
|
引入设置
引入 translate.js 代码前备份:
Shell1
| ❯ cp node_modules/hexo-theme-icarus/layout/common/comment.jsx node_modules/hexo-theme-icarus/layout/common/navbar.jsx node_modules/hexo-theme-icarus/layout/common/comment.jsx node_modules/hexo-theme-icarus/layout/common/navbar.jsx.bak
|
引入 translate.js 代码:
node_modules/hexo-theme-icarus/layout/common/navbar.jsx1 2
| <div class="navbar-end"> + <script src="//lib.baomitu.com/translate.js/3.2.1/translate.js"></script><link rel="stylesheet" href="/css/translate.css"/><script src="/js/translate_lib.js" defer=""></script><a class="navbar-item" id="translate" rel="noopener" title="翻译"><i class="fa fa-language"></i></a>
|
评论区国际化
translate.js 无法翻译 <iframe>
元素内的文字。
giscus 的所有元素在 <iframe>
元素内。
我应在 giscus 加载前获取访问者的语言,在 giscus 加载时替换 giscus 的 data-lang
。
source/js/trans_giscus.js1 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
| const getCurrentLanguage = function () { var lang = translate.language.getCurrent(); var giscus_lang = "zh-CN"; switch (lang) { case "chinese_traditional": giscus_lang = "zh-TW"; break; case "english": giscus_lang = "en"; break; case "spanish": giscus_lang = "es"; break; case "japanese": giscus_lang = "ja"; break; case "korean": giscus_lang = "ko"; break; case "french": giscus_lang = "fr"; break; case "arabic": giscus_lang = "ar"; break; default: giscus_lang = "zh-CN"; break; } return giscus_lang; };
var SetupGiscus = function (giscus_lang) { const script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://giscus.app/client.js";
script.setAttribute("data-repo", "PJ-568/PJ-568.github.io"); script.setAttribute("data-repo-id", "R_kgDOHqFAPw"); script.setAttribute("data-category", "Announcements"); script.setAttribute("data-category-id", "DIC_kwDOHqFAP84CYqBu");
script.setAttribute("data-mapping", "title"); script.setAttribute("data-strict", "1"); script.setAttribute("data-reactions-enabled", "1"); script.setAttribute("data-emit-metadata", "0"); script.setAttribute("data-input-position", "top"); script.setAttribute("data-theme", "light_tritanopia"); script.setAttribute("data-lang", giscus_lang); script.setAttribute("data-loading", "lazy");
script.crossOrigin = "anonymous"; script.async = true; if (document.getElementById("giscus-container") != null) { document.getElementById("giscus-container").appendChild(script); } };
window.addEventListener('load', () => SetupGiscus(getCurrentLanguage()));
|
node_modules/hexo-theme-icarus/layout/common/comment.jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| return <div class="card"> <div class="card-content"> <h3 class="title is-5">{__('article.comments')}</h3> - <script src="https://giscus.app/client.js" - data-repo="Username/Username.github.io" - data-repo-id="XXxXXXXxXXXx" - data-category="Announcements" - data-category-id="XXX_xxXXxXXXxxXXXX" - data-mapping="title" - data-strict="1" - data-reactions-enabled="1" - data-emit-metadata="0" - data-input-position="top" - data-theme="light_tritanopia" - data-lang="zh-CN" - crossorigin="anonymous" - async> - </script> + <div id="giscus-container"></div>
|
node_modules/hexo-theme-icarus/layout/common/navbar.jsx1 2 3
| <script src="//lib.baomitu.com/translate.js/3.2.1/translate.js"></script><link rel="stylesheet" href="/css/translate.css"/><script src="/js/translate_lib.js" defer=""></script><a class="navbar-item" id="translate" rel="noopener" title="翻译"><i class="fa fa-language"></i></a> + <script src="/js/trans_giscus.js"></script> {Object.keys(links).length ? <Fragment>
|
怎么 hexo clean | hexo s
测试没效果?不管了,我直接推上线。说不定上线了就好了。
确实好了。
自定义页脚
_config.icarus.yml1 2 3
| footer: # Copyright text + copyright: <a href="//icp.gov.moe/?keyword=20230568" target="_blank" rel="noopener">萌 ICP 备 20230568 号</a> 未特殊声明文章默认遵循 CC BY 4.0 许可协议
|
压缩静态文件
Hexo-neat
安装:
Shell1 2 3 4
| ❯ npm install hexo-neat --save
+ hexo-neat@1.0.9 added 17 packages from 14 contributors in 4.12s
|
配置:
_config.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| + ## hexo-neat + neat_enable: true + neat_html: + enable: true + exclude: + - games/lib/** + neat_css: + enable: true + exclude: + - '*.min.css' + neat_js: # js 一模炸,别动 + enable: false + mangle: true + output: + compress: + exclude: + - '*.min.js'
|
自动推送至搜索引擎
hexo-submit-urls-to-search-engine
具体请依据配置文档。
安装
Shell1 2 3 4
| ❯ npm install --save hexo-submit-urls-to-search-engine
+ hexo-submit-urls-to-search-engine@2.1.0 added 79 packages from 81 contributors in 9.513s
|
配置:
_config.yml1 2 3 4 5 6 7 8 9 10
| # Deployment ## Docs: https://hexo.io/docs/one-command-deployment - deploy: - type: '' + # deploy: + # type: '' + deploy: + - type: cjh_google_url_submitter + - type: cjh_bing_url_submitter + - type: cjh_baidu_url_submitter
|
_config.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| + hexo_submit_urls_to_search_engine: + submit_condition: count #链接被提交的条件,可选值:count | period 现仅支持count + count: 10 # 提交最新的10个链接 + period: 900 # 提交修改时间在 900 秒内的链接 + google: 0 # 是否向Google提交,可选值:1 | 0(0:否;1:是) + bing: 1 # 是否向bing提交,可选值:1 | 0(0:否;1:是) + baidu: 1 # 是否向baidu提交,可选值:1 | 0(0:否;1:是) + txt_path: submit_urls.txt ## 文本文档名, 需要推送的链接会保存在此文本文档里 + baidu_host: https://Username.github.io ## 在百度站长平台中注册的域名 + baidu_token: 请按照文档说明获取 ## 请注意这是您的秘钥, 所以请不要把它直接发布在公众仓库里! + bing_host: https://Username.github.io ## 在bing站长平台中注册的域名 + bing_token: 请按照文档说明获取 ## 请注意这是您的秘钥, 所以请不要把它直接发布在公众仓库里! + google_host: https://Username.github.io ## 在google站长平台中注册的域名 + google_key_file: Project.json #存放google key的json文件,放于网站根目录(与hexo _config.yml文件位置相同),请不要把json文件内容直接发布在公众仓库里! + google_proxy: http://127.0.0.1:8080 # 向谷歌提交网址所使用的系统 http 代理,填 0 不使用 + replace: 0 # 是否替换链接中的部分字符串,可选值:1 | 0(0:否;1:是) + find_what: http://Username.github.io/blog + replace_with: https://cjh0613.com
|
持续集成
.github/workflows/Release.yml1 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
| name: 【部署】
on: workflow_dispatch: push: paths: - '**' - '!LICENSE' - '!.github\workflows\**'
jobs: hexo-deployment: runs-on: ubuntu-latest env: TZ: Asia/Shanghai
steps: - name: Checkout source uses: actions/checkout@v4 with: fetch-depth: 0 submodules: true
- name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '14.17.0'
- name: Restore file modification time run: | git ls-files -z | while read -d '' path; do touch -d "$(git log -1 --format="@%ct" "$path")" "$path"; done
- name: Install dependencies & Generate static files run: | node -v npm i -g hexo-cli npm i [ -d auth ] && [ "$(ls -A auth)" ] && cp -vrf auth/* source/ || echo "auth 为空或不存在" hexo clean hexo g hexo d
- name: Generate the sitemap id: sitemap uses: cicirello/generate-sitemap@v1 with: path-to-root: ./public base-url-path: https://blog.pj568.sbs/
- name: 移动特定文件 run: | cp -v ./README.md public/README.md
- uses: JamesIves/github-pages-deploy-action@v4 env: GIT_NAME: PJ-568 GIT_EMAIL: ${{ secrets.GIT_EMAIL }} REPO: github.com/PJ-568/Blog with: token: ${{ secrets.GH_TOKEN }} branch: master repository-name: PJ-568/Blog folder: ./public
|
持续集成应用文件更改
刚改的几个文件都在本地 node_modules/
文件夹内。它不被上传。服务器安装依赖也会覆盖。
将有更改的文件放在 assets/
文件夹,在安装依赖后且部署前将它们覆盖到指定位置。
Shell1 2 3 4 5 6 7 8 9
| ❯ ls assets/ ╭───┬────────────────────┬──────┬────────┬─────────────╮ │ # │ name │ type │ size │ modified │ ├───┼────────────────────┼──────┼────────┼─────────────┤ │ 0 │ assets\comment.jsx │ file │ 1.8 KB │ 7 hours ago │ │ 1 │ assets\footer.jsx │ file │ 3.8 KB │ 4 hours ago │ │ 2 │ assets\head.jsx │ file │ 8.3 KB │ 3 hours ago │ │ 3 │ assets\navbar.jsx │ file │ 4.7 KB │ 6 hours ago │ ╰───┴────────────────────┴──────┴────────┴─────────────╯
|
.github/workflows/Release.yml1 2 3 4 5 6 7 8 9
| run: | node -v npm i -g hexo-cli npm i + cp -rf assets/* node_modules/hexo-theme-icarus/layout/common/ [ -d auth ] && [ "$(ls -A auth)" ] && cp -vrf auth/* source/ || echo "auth 为空或不存在" hexo clean hexo g hexo d
|