hexo+next搭建博客
前情提要:不花一分钱搭建一个带有后台的个人 Blog 。
分为两个部分:1. 用 github 和 hexo 搭建不带后台的博客。 2. 迁移到 netlify 上,加入后台。
本站的搭建经历了很多的步骤,现记录如下,写一个备忘,也是帮助其他人。
hexo+github
首先是 hexo 的使用。先前我了解过 github pages 的使用,原理很简单: github 对每一个项目都可以建立一个 page ,前提是代码仓库的根目录上至少要有一个 index.html
。生成的 page 放在域名 username.github.io/repositoryname
上。当 repositoryname
和 username
相同的时候,域名简化成 username.github.io
,很适合建立个人博客。这样的博客都是静态的,也就是说,网站的所有文件都是生成好的,直接上传到 github 即可。
那么怎么生成网站的静态文件呢?使用 hexo 、 hugo 等静态网站生成器就可以完成。生成完的网站文件在 public
目录下,将 public
目录上传到 github 即可。
hexo
首先来看hexo。
参考官方教程就可以完成基础配置。这里简单归纳一下:
安装
hexo 要由 node.js 的软件包管理器 npm 安装。此外 hexo 依赖于 git ,所以要现安装 node.js 和 git 。
(不是非要 Linux。关于 npm、hexo 的脚本在 powershell 就可以运行。)1
2
3
4yay -S nodejs git
# sudo pacman -S nodejs git
# sudo apt install nodejs git-core
# sudo yum install nodejs git-core
对于 Windows,Mac 用户:
然后使用 npm 安装 hexo :1
sudo npm install -g hexo-cli
关于 windows 系统上禁止运行脚本
在设置里查找 powershell,找到并打开“允许本地powershell脚本在未签名的情况下运行”。
建站
选择你想要建立blog的路径。假设想要建立在 ~/Blog
文件夹:1
cd ~; hexo init Blog; cd Blog; npm install
(~
是 Linux 的主目录,类似 Windows 的 C:/Users/Admin/
)
ok。现在 hexo 已经可以使用。默认有一篇文章 helloworld
。注意:如果 hexo 一篇文章都没有,则无法生成网站。
此时网站的目录如下:1
2
3
4
5
6
7
8.
├── _config.yml
├── package.json
├── scaffolds
├── source
| ├── _drafts
| └── _posts
└── themes
_config.yml
是配置网站的地方, source
里面存储的都是网站的文章,其中 _posts
的内容会被编译成 html , _drafts
目录会被忽略,而其他文件会原样复制到网站的根目录。 themes
文件夹里存储了主题文件。下文说的 next 主题就要放在这里。
在开始配置之前,先来试一试吧!你将看到默认主题 landscape 下的 helloworld 文章。1
hexo clean && hexo s
这将会在你的计算机上运行一个网站实例,一般来说会在 localhost:4000
。这意味着跟你在同一局域网的人就可以访问这个网站。如果 4000 端口被占用,你也可以选择其他端口:1
hexo clean && hexo s -p 1234
这将会在 localhost:1234
上运行一个网站实例。
无论在哪个端口,它看上去应该像这样:
配置
_config.yml
文件包括了站点的基础属性。
其中的大部分内容我们不用改。我们只要改基本信息:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# Site
title: Hexo
subtitle: ''
description: ''
keywords:
author: John Doe
language: en
timezone: ''
# URL
## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project'
url: http://example.com
permalink: :year/:month/:day/:title/
permalink_defaults:
pretty_urls:
trailing_index: true # Set to false to remove trailing 'index.html' from permalinks
trailing_html: true # Set to false to remove trailing '.html' from permalinks
这里是网站的基本信息。 title
是主标题, subtitle
是副标题。 description
可以是你的一句座右铭, keywords
越多越好,用逗号隔开。 author
写你的名字, language
选 zh-CN
, timezone
选 Asia/Shanghai
。 url
就填写你的网址( username.github.io
)。
再试一下 hexo s
,就可以发现网站标题等改变了。
github
好。现在我们考虑怎么把网站放到 github 上:
首先我们要知道怎么生成 public
文件夹:1
hexo clean && hexo g
现在 Blog
目录中就有了 public
目录。我们可以手动把它 push 到 git 仓库上。1
git push [email protected]:username/username.github.io --set-upstream main -f
这里前提是要配置好 ssh-key 。
那么打开 username.github.io 的仓库配置,settings-pages ,选择打开 pages (默认应该是打开的),再打开网站 username.github.io
就可以看到刚刚生成的网址了。
自动化
但是这么做还是太 low 了。 hexo 有一个功能 deploy ,可以将已经生成好的 public
文件夹自动上传,不过需要我们配置一下。
安装插件 hexo-deployer-git
1
npm install hexo-deployer-git --save
然后打开之前提到的 _config.yml
,找到deploy字段,更改如下:1
2
3
4
5
6# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
type: git
repo: [email protected]:username/userame.github.io
branch: main
现在只要一行命令,就可以直接编译并部署了。1
hexo clean && hexo d -g # or hexo g -d
新建文章
hexo 新建文章最好使用命令:1
hexo new #postname
文章无需后缀名,自动使用 .md
后缀。如果题目中有空格或特殊字符,加上双引号:1
hexo new "postname"
hexo 的文章开头存储了一些 yaml 信息,用 ---
表示开头结尾。这些信息被称为 front-matter
,记录了文章的标题、日期等,文章的属性都在 front-matter
上。
新建页面
hexo 支持建立一些页面,同时也支持对文章进行分类和标签,分类和标签信息都存储在 front-matter
中。
分类和标签
在 hexo 中,分类和标签不是一个东西。他们的形式很像:1
2
3
4
5
6
7
8categories: #分类
-category1
-category2
#...
tags: #标签
-tag1
-tag2
#...
但是他们的含义不一样。 categories 表示文章属于 category1 类别中的 category2 类别,而 tags 表示文章既是 tag1 标签,又是 tag2 标签。可以看到 categories 是有严格父子关系的,而 tags 是并列的。
如果希望读者能够通过分类和标签索引文章,需要新建 categories 页面和tags页面:1
hexo new page categories && hexo new page tags
此时在 source
文件夹下就会多出 categories 文件夹和 tags 文件夹。文件夹中有一个 index.md
。打开 markdown ,在 front-matter
中分别加入 type: "categories"
和 type: "tags"
。正文留空。就完成了构建。
关于
同理,新建 about 页面。1
hexo new page about
编辑 source/about/index.md
,加入 type: "about"
,然后在正文部分编辑自我介绍内容。
404
腾讯公益404接入方法如下:1
<script type="text/javascript" src="//qzonestyle.gtimg.cn/qzone/hybrid/app/404/search_children.js" charset="utf-8" homePageUrl="http://yoursite.com/yourPage.html" homePageName="回到我的主页"></script>
直接在 source
目录下新建一个 404.md
(手动新建),加入上面一段就好。
其他插件
next 内置插件
next 在蛰伏了许久之后,终于迎来了 next8.0。
现在已经有超多的内置功能和社区维护插件。内置功能在这:Link
文章排序
hexo 默认的排序是根据发布日期。有时我们会希望将文章置顶或按照 update 日期排序,可以利用一个插件实现:1
2npm uninstall hexo-generator-index --save
npm install hexo-generator-index-plus --save
然后将 _config.yml
中的 index-generator
字段删除,添加如下配置:1
2
3index_generator_plus:
path: ''
per_page: 10
无需其他改动,只要在 front-matter
中加入 top: #你的值
就可以排序。 top 越大越靠前。
spoiler
编程向的 Blog 难免会有大量代码,这时如果直接放着就很丑。可以利用 hexo-sliding-spoiler
实现折叠代码,而且 js 效果还算不错。
用法如下:1
2
3
4{% spoiler /*想折叠内容的概述,如 Code*/ %}
//...折叠内容
//...内部仍然支持markdown语法
{% endspoiler %}
示例:
1 |
|
安装:1
npm install hexo-sliding-spoiler --save
bug 修复: spoiler 内容默认超过一定长度就会隐藏。打开 node_modules/hexo-sliding-spoiler/assets/spoiler.css
编辑 .spoiler.expanded .spoiler-content
中的 overflow
选项,改为 auto
,就会出现滚轮滑动来查看。
note
感谢 @Eray 提醒,next 内置了可以折叠的 note 功能。并且还有比较完整的高亮设计,跟 OI-wiki 的用法差不多。
可以代替 spoiler 使用。详见官方 Wiki
示例:
这是一段话。
mathjax
这与主题 next 相关,因此放到 next 中去讲。
sitemap
sitemap 可以用来向百度和谷歌等搜索引擎推荐自己的站点。使用方法也简单:1
npm install hexo-generator-sitemap hexo-generator-baidusitemap --save
这样网站的根目录下就有 sitemap.txt
、 sitemap.xml
和 baidusitemap.xml
可供提交。
更多插件在 next 中讲解。
next
next 是一个我觉得挺好看并且插件多,社区活跃的主题。
安装
现在 next 不再推荐使用 git 的安装方法, 但是如果想要更高的定制化,推荐使用 git。
1 | npm install hexo-theme-next |
配置
在站点目录下新建配置文件:_config.next.yml
。
建议复制一份官方示例:Link
接下来我们看一看 next 的配置:
PS:以下配置内容如没有就新建。 next 默认有4中主题可选。找到 默认主题是 Muse ,可以逐个试一试。 在 找到 在 找到 在 找到字段 找到字段 找到字段 找到字段 找到字段 next 支持 mathjax 和 katex 。一般来说 katex 渲染快,而且 next 也支持了复制 katex 源码,但是在 mathjax3 之后, katex 和 mathjax 速度差不多,而 mathjax 支持更多样的复制和多种渲染选项,而且支持更多语法,再加之化学方程式的支持,我最终选择了 mathjax 。 想要启用 mathjax ,还需: 同时安装pandoc(非 Linux 用户点这个链接): 评论的插件其实有很多,在多方考虑之后,现在使用的是 OI-wiki 同款的 giscus,最大的好处就是在评论区支持 Mathjax。(曾经用的是utteranc) giscus 官方文档很详细,这里直接放链接:giscus 找到字段 全部为 找到字段 同时安装 找到字段 同时安装 主题
Schemes
:1
2
3
4
5# Schemes
scheme: Muse
#scheme: Mist
#scheme: Pisces
#scheme: Gemini页面
menu
选项中取消你想要的页面的注释:1
2
3
4
5
6
7
8
9menu:
home: / || fa fa-home
about: /about/ || fa fa-user
tags: /tags/ || fa fa-tags
categories: /categories/ || fa fa-th
archives: /archives/ || fa fa-archive
#schedule: /schedule/ || fa fa-calendar
# sitemap: /sitemap.xml || fa fa-sitemap
#commonweal: /404.html || fa fa-heartbeat头像
avatar
字段:1
2
3
4
5
6
7avatar:
# Replace the default image and set the url here.
url: https://images.shwstone.cn/head.jpg
# If true, the avatar will be dispalyed in circle.
rounded: true
# If true, the avatar will be rotated with the cursor.
rotated: truesource
中新建 images
文件夹,里面放入你的图片。 rounded
设置圆形, rotated
设置鼠标放上去就旋转。社交账号和友链
social
字段:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25social:
#GitHub: https://github.com/yourname || fab fa-github
#E-Mail: youremail || fa fa-envelope
#Weibo: https://weibo.com/yourname || fab fa-weibo
#Google: https://plus.google.com/yourname || fab fa-google
#Twitter: https://twitter.com/yourname || fab fa-twitter
#FB Page: https://www.facebook.com/yourname || fab fa-facebook
#StackOverflow: https://stackoverflow.com/yourname || fab fa-stack-overflow
#YouTube: https://youtube.com/yourname || fab fa-youtube
#Instagram: https://instagram.com/yourname || fab fa-instagram
#Skype: skype:yourname?call|chat || fab fa-skype
social_icons:
enable: true
icons_only: false
transition: false
# Blog rolls
links_settings:
icon: fa fa-link
title: Links
# Available values: block | inline
layout: block
links:social
中添加你的社交账号,不局限于给出选项,也可以自己添加。social_icons
控制显示时是否有图标。links
设置友链。打赏
说不定有好心人呢?找到 reward
字段:1
2
3
4
5
6
7
8
9
10
11reward_settings:
# If true, reward will be displayed in every article by default.
enable: true
animation: false
comment: "如果阅读本篇文章需要付费,你愿意为此支付1块钱吗?"
reward:
wechatpay: https://images.shwstone.cn/weixin.jpg
#alipay: https://images.shwstone.cn/alipay.png
#paypal: https://images.shwstone.cn/paypal.png
#bitcoin: https://images.shwstone.cn/bitcoin.pngreward
中设置你的收款码。方法同头像。代码块设置
codeblock
:1
2
3
4
5
6
7
8
9
10
11
12codeblock:
# Code Highlight theme
# Available values: normal | night | night eighties | night blue | night bright | solarized | solarized dark | galactic
# See: https://github.com/chriskempson/tomorrow-theme
highlight_theme: normal
# Add copy button on codeblock
copy_button:
enable: true
# Show text copy result.
show_result: true
# Available values: default | flat | mac
style:highlight_theme
配置风格,可以自行尝试。copy_button
配置复制按钮一键回到顶部
back2top
:1
2
3
4
5
6back2top:
enable: true
# Back to top in sidebar.
sidebar: true
# Scroll percent label in b2t button.
scrollpercent: true阅读进度
reading_progres
:1
2
3
4
5
6reading_progress:
enable: true
# Available values: top | bottom
position: top
color: "#37c6c0"
height: 3pxposition
中 top
在顶部, bottom
浮动在按钮上。你的Github
github_banner
:1
2
3
4github_banner:
enable: true
permalink: https://github.com/yourname
title: Fork me on GitHubtitle
可修改mathjax
math
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15math:
# Default (false) will load mathjax / katex script on demand.
# That is it only render those page which has `mathjax: true` in front-matter.
# If you set it to true, it will load mathjax / katex script EVERY PAGE.
every_page: true
mathjax:
enable: true
# Available values: none | ams | all
tags: none
katex:
enable: false
# See: https://github.com/KaTeX/KaTeX/tree/master/contrib/copy-tex
copy_tex: falseevery_page
配置是否对每篇文章开启渲染。建议开启,不然每篇文章开头都要加上 front-matter
: mathjax: true
。1
2npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-pandoc hexo-math --save1
2
3
4yay -S pandoc
# sudo pacman -S pandoc
# sudo apt install pandoc
# sudo rpm install pandoc评论
访问量统计
busuanzi_count
:1
2
3
4
5
6
7
8
9
10# Show Views / Visitors of the website / page with busuanzi.
# Get more information on http://ibruce.info/2015/04/04/busuanzi
busuanzi_count:
enable: true
total_visitors: true
total_visitors_icon: fa fa-user
total_views: true
total_views_icon: fa fa-eye
post_views: true
post_views_icon: fa fa-eyetrue
即可。站内搜索
localsearch
:1
2
3
4
5
6
7
8
9
10
11
12
13# Local Search
# Dependencies: https://github.com/theme-next/hexo-generator-searchdb
local_search:
enable: true
# If auto, trigger search by changing input.
# If manual, trigger search by pressing enter key or search button.
trigger: auto
# Show top n results per article, show all results by setting to -1
top_n_per_article: 1
# Unescape html strings to the readable one.
unescape: false
# Preload the search data when the page loads.
preload: falsehexo-generator-searchdb
:1
npm install hexo-generator-searchdb --save
分享文章
needmoreshare
: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# NeedMoreShare2
# Dependencies: https://github.com/theme-next/theme-next-needmoreshare2
# For more information: https://github.com/revir/need-more-share2
# iconStyle: default | box
# boxForm: horizontal | vertical
# position: top / middle / bottom + Left / Center / Right
# networks:
# Weibo | Wechat | Douban | QQZone | Twitter | Facebook | Linkedin | Mailto | Reddit | Delicious | StumbleUpon | Pinterest
# GooglePlus | Tumblr | GoogleBookmarks | Newsvine | Evernote | Friendfeed | Vkontakte | Odnoklassniki | Mailru
needmoreshare:
enable: true
cdn:
js: //cdn.jsdelivr.net/gh/theme-next/theme-next-needmoreshare2@1/needsharebutton.min.js
css: //cdn.jsdelivr.net/gh/theme-next/theme-next-needmoreshare2@1/needsharebutton.min.css
postbottom:
enable: true
options:
iconStyle: box
boxForm: horizontal
position: bottomCenter
networks: Weibo,Wechat,Douban,QQZone,Twitter,Facebook,
float:
enable: false
options:
iconStyle: box
boxForm: horizontal
position: middleRight
networks: Weibo,Wechat,Douban,QQZone,Twitter,Facebookhexo-next-share
:1
npm install hexo-next-share
效果
就像你现在看到的这样。
netlify
github 站虽好,但是一来访问慢,二来不能被百度爬到。所以我决定迁移到 netlify 。
这是一个提供免费的(基础服务免费)网页托管,持续部署的网站, CDN 也很快,非常适合我们使用。而且 netlify 还有 CMS (后台)系统,可以在线修改你的文章,原来必须要服务器+域名才能完成的事,被我们免费做到,岂不是爽歪歪?
建站
netlify 提供自动部署服务,如果想要用他的 CMS ,就不能只把 public
文件夹传上去了,我们要把整个 Blog 文件夹都传上去。
在 github 上新建一个代码仓库 Blog ,然后把本地文件夹传上去:1
git init && git add -A && git commit -a -m "init" && git push [email protected]:username/Blog.git
随后在netlify中选择用 github 登陆。新建一个站点,选择绑定到 github 仓库,选择刚刚新建的Blog仓库。在站点的构建命令中填写 npm install && npm build
,发布目录填 public
。
然后 netlify 会自动帮你运行部署,相当与我们在本地运行 hexo g
,然后通过 public
文件夹访问站点。不过这一切都是由 netlify 的机器来做的。在站点配置中你可以更改自己网站的名字,任意选取吧!
这个东西他有个好处,就是对于小型博客部署时间短。因为 netlify 会将你部署所需的环境、插件作为缓存存起来,不需要每次都安装,而不像 github 的 CI ,每次都要装依赖,甚至 pandoc 都要重装一遍。所以虽然 netlify 只有 300 分钟一个月的构建时间,但是绝对够用。
如果不够用了可以考虑关闭 netlify 的自动部署,然后在 Blog 仓库中启用 Action ,配置构建指令并部署到 netlify 。这样子就会有2000分钟的构建时间,但每次部署都要多花1分多钟。不过这样还是可以使用CMS的。
既然已经迁移到了 netlify ,我们可以让原来的 github page重定向到 netlify ,避免流量流失。将 github page 的仓库的内容全部删除,添加 index.html
:1
2
3
4
5
6
7
8
9<html>
<head>
<title>ShwBlog</title>
<meta http-equiv="refresh" content="1;url= https://shwstone.netlify.app/ ">
</head>
<body>
<script> alert("本站迁移至https://yoursitename.netlify.app/,请您记住新网址,将为您自动跳转。"); </script>
</body>
</html>
debug
如果你按照上文配置了 hexo-sliding-spoiler
,你就会发现长的内容又被隐藏了,这是因为 node_modules
作为插件的安装位置,并不会被push到github上,netlify重新安装了插件,采用了默认配置。
解决办法如下:
新建一个文件夹 prebuild
,将更改后的文件复制到其中。 prebuild
里面添加一个文件 file
, file
中每一行存储需要更改的文件路径和更改后的文件路径,如下:1
prebuild/spoiler.css node_modules/hexo-sliding-spoiler/assets/spoiler.css
然后在网站根目录下新建 prebuild.sh
并 chmod +x prebuild.sh
,编辑如下:1
2
3
4
5
while read line
do
cp $line -f
done < prebuild/file
(Windows 用户照着抄就好了。 Netlify 自动构建的环境是 Linux,所以要这么写)
push 到 github 上。
最后在 netlify 的构建指令中加上一条,改为 npm install && ./prebuild.sh && npm run build
。
PS:如果 windows 无法执行 chmod 的话,把构建指令改为 npm install && /bin/sh ./prebuild.sh && npm run build
如果还有别的文件要更改,复制到 prebuild
文件夹并且在 file
中添加就行了。
百度验证
百度站长平台要求你验证自己的网站,可以通过往 </head>
标签之前插入一个 <meta name="baidu-site-verification" content="***" />
来完成。 netlify 支持在网站 html 中注入代码:进入 netlify.app ,选择 site-settings ,找到 build & deploy 中的 Snippet injection ,选择在 </head>
或 </body>
标签前加入代码。
CMS
接下来我们来看后台的使用。
upd:netlify-cms 已经被弃用,现在使用 decap-cms。
配置
进入 netlify.app ,选择 site-settings ,找到 build & deploy 中的 Snippet injection ,在 </body>
标签前加入:1
2
3
4
5
6
7
8
9
10
11
12
13<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
<script>
if (window.netlifyIdentity) {
window.netlifyIdentity.on("init", user => {
if (!user) {
window.netlifyIdentity.on("login", () => {
document.location.href = "/admin/";
});
}
});
}
</script>
<!--netlify cms 有一个小 bug ,登录时需要手动刷新。这是自动刷新的代码-->
然后在 source
文件夹下新建一个文件夹:source/admin
,再建两个文件:source/admin/index.html
,source/admin/config.yml
分别编辑如下: config.yml index.html1
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
36backend:
name: github
repo: # repo name
branch: main # Branch to update (optional; defaults to master)
site_url: https://shwstone.cn
display_url: https://shwstone.cn
# logo_url: https://images.shwstone.cn/
locale: 'cn'
# This line should *not* be indented
publish_mode: editorial_workflow
# This line should *not* be indented
media_folder: "source/images" # Media files will be stored in the repo under images/uploads
public_folder: "source"
# A list of collections the CMS should be able to edit
collections:
# Used in routes, ie. : /admin/collections/:slug/edit
- name: "posts"
# Used in the UI, ie.: "New Post"
label: "Post"
folder: "source/_posts" # The path to the folder where the documents are stored
sort: "date:desc"
create: true # Allow users to create new documents in this collection
editor:
preview: true
fields: # The fields each document in this collection have
- {label: "Title", name: "title", widget: "string"}
- {label: "Publish Date", name: "date", widget: "datetime", format: "YYYY-MM-DD HH:mm:ss", date_format: "YYYY-MM-DD", time_format: "HH:mm:ss", required: false}
- {label: "Tags", name: "tags", widget: "list", required: false}
- {label: "Categories", name: "categories", widget: "list", required: false}
- {label: "Body", name: "body", widget: "markdown", required: false}
- {label: "Comments", name: "comments", widget: "boolean", default: true, required: false}
- {label: "Top", name: "top", widget: "number", value_type: "int", default: 2, required: false}1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex" />
<title>Content Manager</title>
</head>
<body>
<!-- Include the script that builds the page and powers Decap CMS -->
<script src="https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js"></script>
</body>
</html>
注意 backend
中的 repo & branch
要与你的实际分支相匹配。
然后在 netlify 中找到 site-settings-identity ,找到 git-gateway ,点击启用,选择 Blog 仓库。
这样你就可以在 你的网址/admin
中看到登陆界面了。
另外,如果出现权限问题,请按照 Netlify-docs 配置 auth。
自己注册一个 admin 账户,然后在 identity 中关闭注册,只允许邀请,保证安全。
ok 。尽情享受 CMS 吧!
To do
decap CMS 不支持 latex ,并且 bug 较多,我以后有时间可能会把 Luogu 的 Markdown*Palettes 嵌入到 netlify 的 markdown 编辑器里,自己做一个小部件,或者哪位大佬帮我写一下吧 qwq 。