0%

Hexo NexT 深度定制

Hexo是一个基于NodeJS简洁高效的博客框架, 本文详细介绍了自己基于Hexo和NexT主题搭建自己个人网站,并且部署到AWS和阿里云ECS服务上的过程。并且深度定制了自己的个人网站,仅作为自己的一个备忘和对他人的一份有些许价值的参考。

阿里云服务器端

购买ECS服务

之前是利用GitHub Pages + Hexo 部署的博客,因为强迫症想要更加全面的掌控自己的博客,决定在自己的服务器上部署Hexo博客。

现在各大厂商都有自己的ECS服务,同时针对学生也有固定的学生优惠。我选择的是阿里云云翼计划的云服务器ECS服务。

配置如下

  • 1核CPU Intel Xeon E5-2682 v4
  • 2G DDR4 内存
  • 1M带宽 VPC专有网络, I/O 优化
  • 40G系统盘

这一套下来官网价格得要1452RMB,用学生优惠下来只需要114RMB,显然实惠很多。

购买域名

既然都已经有了自己的服务器了,自然就想,为何不整一套自己的域名呢?

域名可以在国外知名域名注册厂家Godaddy和NameCheap等购买,也可以使用国内的阿里云万网和腾讯云的域名注册服务购买。但是看着国外域名随随便便一年十几刀的费用,我还是老老实实用万网的服务买的域名。

houmin.cc用160RMB买了10年的域名服务,从2017年到2027年。

因为某些不可知的因素,cc域名从2018年起不能在国内备案了,导致我现在这个域名也一直不能备案,不过还是可以解析的。购买域名服务后,修改域名解析服务,将域名指向我们自己的阿里云服务器。

服务器环境搭建

配置安全组规则

由于阿里云是默认不授权80端口的访问的,所以我们要手动配置。

打开阿里云服务器管理控制台->点击左侧安全组->点击右侧的配置规则->点击添加安全组规则

配置服务器环境

服务器采用的是Ubuntu 16.04,作为一个网站,必定要有一个web server,这里采用的是Nginx

1
sudo apt-get install nginx

这个时候打开浏览器,输入服务器的公网IP地址,就可以看到Nginx的默认网页了。

关于Nginx当前采用的是默认配置,我们的目标是让这个网站的默认地址指向我们的博客,是不是默认的这个欢迎界面。这就需要我们去修改Nginx的默认配置。Nginx的配置文件在Ubuntu下放在了/etc/nginx的目录下,我们可以看到该目录下有sites-availablesites-enabled,其中sites-enabled里面的default就是sites-available下面default的一个软链接。打开default我们可以看到

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
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;

# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;

root /var/www/html;

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;

server_name _;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php7.0-fpm:
# fastcgi_pass unix:/run/php/php7.0-fpm.sock;
#}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

当前Nginx监听在80端口,默认没有打开HTTPS,同时网站的源代码放在了/var/www/html目录下。进入这个目录,我们也确实可以看到一个index.nginx-debian.html文件。这就是我们看到的默认Nginx的欢迎页面。

为了创建我们自己的网站,我们需要类似的有同样的配置

  • 创建存放网站源文件的目录,这里我们创建的是/var/www/houmin.cc
  • 创建我们自己网站的配置文件,在/etc/nginx/sites-available中,这里我们叫houmin.cc
  • /etc/nginx/sites-enabled中删去default,并且创建一个对houmin.cc配置文件的软链接。
  • 删除/etc/nginx/sites-enabled中的default
1
2
3
4
5
$ sudo mkdir -p /var/www/houmin.cc
$ cd /etc/nginx/sites-enabled
$ sudo ln -s /etc/nginx/sites-available/houmin.cc houmin.cc
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo systemctl restart nginx.service

其中新的配置文件中只是修改了网站root的目录,其他地方没有做修改。这时候在/var/www/houmin.cc目录下放置一个新的html文件,输入公网IP应该可以新的网页了。

配置Git服务

网站的源文件通过git进行版本管理,每一次更新源文件之后,可以通过git的hook操作自动更新到Nginx的目录下。因此,我们需要在服务器上面搭建一个自己的git服务器,具体的操作如下:

  • 创建git用户,并且授予其sudo权限
    1
    2
    $ sudo adduser git
    $ sudo usermod -aG sudo git
    这时候在服务器上以git用户登陆,可以在/home/git目录下创建repositories目录,专门用作git服务器放置repo的地方。
1
2
git@cosmos:~/repositories$ git init --bare blog.git
Initialized empty Git repository in /home/git/repositories/blog.git/

这时候在客户端应该是可以clone这个repo的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git clone git@houmin.cc:/home/git/repositories/blog.git
Cloning into 'blog'...
git@houmin.cc's password:
warning: You appear to have cloned an empty repository.
$ touch hello.md
$ echo "Hello, Git" >> hello.md
$ git add hello.md
$ git commit -m "Add hello.md"
$ git push -u origin
git@houmin.cc's password:
Counting objects: 3, done.
Writing objects: 100% (3/3), 219 bytes | 219.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To houmin.cc:/home/git/repositories/blog.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

为了避免输入密码,可以在本地机器执行
1
$ ssh-copy-id git@houmin.cc

为了实现自动部署,我们需要利用git的hook功能。

我们进入到blog.git目录,

1
2
3
4
git@cosmos:~/repositories/blog.git/hooks$ cat post-receive
git --work-tree=/var/www/houmin.cc --git-dir=/home/git/repositories/blog.git checkout -f
git@cosmos:~/repositories/blog.git/hooks$ chmod +x post-receive
git@cosmos:~$ sudo chown -R git:git /var/www/houmin.cc

这里通过创建post-receive这个hook,在每次git push将项目最新的文件复制到work tree下

通过这种方式,是可以看到/var/www/houmin.cc目录下的文件实时的发生更新。为了能够使用git用户更新houmin.cc目录下的文件,需要将该目录的所有者更改为git。

这时候通过ip访问,是可以看到Nginx的默认网页的。

阿里云劫持未备案的请求

这个时候,如果通过域名访问的话,会告诉你houmin.cc没有备案。也就是说,通过访问 http://houmin.cc阿里云会自动识别这个域名所属的服务器没有备案过,会自动劫持请求。

啊是的,你现在也不让我备案了啊(工信部在2018年停掉了cc域名的备案),怎么办呢?查阅资料发现,有人说可以通过开启HTTPS解决这个问题,再仔细一看这个是在2019年上半年的解决方案,阿里云在2019年年中的时候就将没有备案的云服务器通过https的请求也给劫持了。

然后在整https的时候也试了好几种方案,

  • let’s encrypt
  • acme.sh自动
  • cloudflare免费十年证书

采用这三种方案的时候,都因为访问阿里云服务器被劫持了导致没能成功。为了解决这个问题,可以有两个方案

  • 重新申请可以备案的域名,老老实实备案,这个需要20天的时间
  • 使用国外的云服务,比如AWS,可以先免费白嫖一年

这两个方案我同时都在进行,一边买了houmin.site十年的域名,一边又申请了AWS的免费一年的EC2服务。

现在的状态:

  • 备案时间较长,仍在进行中
  • EC2服务申请成功后,将houmin.cc解析到EC2上,这时候是可以成功通过域名访问网站的。

关于HTTPS的部分,可以参考 开启HTTPS

客户端环境搭建

配置信息

1
2
3
4
OS: Ubuntu 18.04 LTS
NodeJS: 8.10.0
Hexo: 4.0.0
NexT: 7.5.0

安装NodeJS

  • 从官网下载系统对应的源码
  • 依次执行以下命令解压编译安装
1
2
3
$ tar -xzvf node-v8.10.0-linux-x64.tar.xz
$ make
$ sudo make install

安装Hexo

1
$ npm install -g hexo

建站

安装 Hexo 完成后,请执行下列命令,Hexo 将会在指定文件夹中新建所需要的文件。

1
2
3
$ hexo init <folder>
$ cd <folder>
$ npm install

新建完成后,指定文件夹的目录如下

1
2
3
4
5
6
7
8
.
├── _config.yml
├── package.json
├── scaffolds
├── source
| ├── _drafts
| └── _posts
└── themes

接下来安装 Hexo 关于启动服务器的插件

1
$ npm install hexo-server --save

这个时候可以启动服务器, 本地查看打开 http://localhost:4000 查看效果效果, 如果不指定端口,默认为4000

1
$ hexo server

主题和配置

这里选择的主题为NexT,下面介绍配置主题的主要步骤

  • 前往 NexT主题发布界面下载主题压缩包
  • 解压并将目录更名为next
  • 将 next 移动至 blog/themes/ 目录下
  • 将 blog 目录下的 _config.yml 文件中的 theme 属性值改为 next
  • 此时主题更换成功,可启动 server 验证效果

将博客部署到阿里云

  • 在阿里云的git服务器上新建blog的仓库
    1
    2
    git@cosmos:~/repositories$ git init --bare blog.git
    # add post-receive hook
  • 安装 hexo 关于 git 的组件

    1
    $ npm install hexo-deployer-git --save
  • _config.yml 中为 git 添加配置

    1
    2
    3
    4
    deploy:
    type: git
    repository: git@houmin.cc:/home/git/repositories/blog.git
    branch: master
  • 执行(每次修改都要执行这些命令才能在github pages看到效果)
    1
    2
    $ hexo generate # generate static files
    $ hexo deploy #Deploy to remote sites

Next主题基本功能配置

Hexo依赖安装

下面是当前配置下需要安装的dependency

hexo安装依赖package.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
{
"name": "hexo-site",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server"
},
"hexo": {
"version": "4.0.0"
},
"dependencies": {
"canvas-nest.js": "^2.0.4",
"hexo": "^4.0.0",
"hexo-abbrlink": "^2.0.5",
"hexo-admin": "^2.3.0",
"hexo-deployer-git": "^2.0.0",
"hexo-douban": "^1.1.3",
"hexo-generator-archive": "^1.0.0",
"hexo-generator-category": "^1.0.0",
"hexo-generator-feed": "^2.0.0",
"hexo-generator-index": "^1.0.0",
"hexo-generator-searchdb": "^1.1.0",
"hexo-generator-sitemap": "^1.2.0",
"hexo-generator-tag": "^1.0.0",
"hexo-related-popular-posts": "^3.0.6",
"hexo-renderer-ejs": "^1.0.0",
"hexo-renderer-marked": "^2.0.0",
"hexo-renderer-stylus": "^1.1.0",
"hexo-server": "^1.0.0",
"hexo-symbols-count-time": "^0.6.3",
"hexo-tag-aplayer": "^3.0.4",
"hexo-tag-dplayer": "^0.3.3"
}
}

可以在博客目录下执行下面命令即可安装上所有的依赖

1
$ sudo npm install --production

定制favicon

文件位置: blog/themes/next/_config.yml
1
2
3
4
5
6
7
favicon:
small: /images/favicon-16x16-next.png # 网站小图标
medium: /images/favicon-32x32-next.png # 中等图标
apple_touch_icon: /images/apple-touch-icon-next.png # app_touch上显示图标
safari_pinned_tab: /images/logo.svg # 在Safari浏览器中显示图标
#android_manifest: /images/manifest.json # 安卓默认显示同普通情况下
#ms_browserconfig: /images/browserconfig.xml

网站 favicon 图标可以放到你的 next 主题目录下面的source/images中,然后按照上述相对路径方式引用,这里 favicon 图标不需要非得是 ico 格式的,也可以是 png 或其它图片格式。

如果是有第三方图床放图片链接的,也可以直接改成图片链接。

社交信息

1
2
3
4
social:
GitHub: https://github.com/SimpCosm || github
E-Mail: mailto:weihoumin@gmail.com || envelope
Douban: http://douban.com/people/SimpCosm || douban

这里有一个问题就是豆瓣没有对应的font awesome图标

友情链接

阅读更多

如果不开启阅读更多按钮的话,默认是展示文章中所有内容的,这显然体验不好。

一般都会在文章中插入<!--more-->这种注释形式表示首页展示到注释处为止。或者会使用如下官方配置文件中自带的方式。一般都推荐使用注释的方式,因为下面这种auto_excerpt方式不会保留前面的行文样式,但是注释方式会保留样式。

搜索 auto_excerpt,找到如下:

1
2
3
auto_excerpt:
enable: true
length: 150 #到多少字数后不显示

侧边栏头像设置

1
2
3
4
5
6
7
8
# Sidebar Avatar
avatar:
# 如果放在本地(source/images): /images/avatar.gif
# 如果第三方图床,直接写地址
url: # 此处是头像的地址
rounded: true # 设置头像是否为圆形
opacity: 1 # 设置不透明度,1为完全不透明,0为完全透明
rotated: true # 设置鼠标放到头像上是否旋转

代码设置

1
2
3
4
5
6
codeblock:
heightling_theme: night
copy_button: # 设置是否开启代码块复制按钮
enable: true
show_result: true # 是否显示复制成功信息
style: mac

这里指的是代码块,不是行内代码块,起始写法如下:

1
​```[language] [title] [url] [link-text]
  • [language] 是代码语言的名称,用来设置代码块颜色高亮,非必须;
  • [title] 是顶部左边的说明,非必须;
  • [url] 是顶部右边的超链接地址,非必须;
  • [link text] 如它的字面意思,超链接的名称,非必须。

亲测这 4 项应该是根据空格来分隔,而不是[],故请不要加[]。除非如果你想写后面两个,但不想写前面两个,那么就必须加[]了,要这样写:[] [] [url] [link text]

你看,这是C++代码
1
2
3
4
5
6
#include <iostream>
using namespace std;
int main() {
cout << "hello world!" << endl;
return 0;
}

可以在站点配置文件_config.yml中设置自动高亮

文件位置:hexo/_config.yml
1
2
3
4
5
6
highlight:
enable: true
line_number: true
# 代码自动高亮
- auto_detect: false
+ auto_detect: true

文章元数据设置

元数据就是显示在 home 页的文章创建于、更新于、阅读次数之类的数据,搜索 post_meta,找到如下配置:

1
2
3
4
5
6
7
8
post_meta:
item_text: false # 是否显示对应的文字
created_at: true # 是否显示 创建于
updated_at: # 是否显示 更新于
enabled: true
# 更新日期显示规则,只有更新日期与创建日期不同时,才会显示
another_day: true
categories: true # 是否显示分类信息

文章字数统计设置

由于上面的元数据中没有带文章字数统计功能,需要利用hexo-symbols-count-time插件来完成。在 hexo 站点根目录下使用npm install hexo-symbols-count-time --save命令安装模块后开启上述功能使用。

配置站点配置文件激活插件

1
2
3
4
5
symbols_count_time:
symbols: true
time: true
total_symbols: true
total_time: true

配置主题配置文件

NexT Config
1
2
3
4
5
6
7
8
# Post wordcount display settings
# Dependencies: https://github.com/theme-next/hexo-symbols-count-time
symbols_count_time:
separated_meta: true
item_text_post: true
item_text_total: false
awl: 4
wpm: 275

博客本地搜索

Hexo的NexT主题通过hexo-generator-searchdb这个插件实现搜索本地搜索。它预先生成了一个文本库search.xml,然后传到了网站里面,在本地搜索时候,NexT直接用JS调用这个文件,从而实现了静态网站的本地搜索。

安装完插件后,站点配置文件新增

1
2
3
4
5
search:
path: search.xml
field: post
format: html
limit: 100

主题配置文件

1
2
3
4
5
local_search:
enable: true
trigger: auto
top_n_per_article: 1
unescape: false

RSS订阅

安装插件:

1
npm install hexo-generator-feed --save

刷新主页就可以看到 rss。

文章打赏

主题配置文件

1
2
3
4
5
6
7
8
9
10
11
12
# Reward (Donate)
reward_settings:
# If true, reward would be displayed in every article by default.
# You can show or hide reward in a specific article throuth `reward: true | false` in Front-matter.
enable: true
animation: false
#comment: Donate comment here.

reward:
wechatpay: /images/wechatpay.jpg
#alipay: /images/alipay.png
#bitcoin: /images/bitcoin.png

文章推荐

开启文章推荐功能后可以自动推荐相关内容的文章,在主题配置文件中

1
2
3
4
5
6
7
8
9
10
related_posts:
enable: true # 是否开启
title: 相关文章推荐 # 标题
display_in_home: false # 是否在首页显示,建议为false
params:
maxCount: 5 # 相关文章的最大数量
#PPMixingRate: 0.0
#isDate: false
#isImage: false
isExcerpt: false

开启相关文章推荐需要安装hexo-related-popular-posts模块,即在 hexo 站点根目录下使用npm install hexo-related-popular-posts --save安装模块,然后开启上面的相关文章功能就可以了。

文章版权声明

在主题配置文件中

1
2
3
4
5
creative_commons:
license: by-nc-sa
sidebar: false
post: true # 将false改为true即可显示版权信息
language:

评论系统

在当前免费开源的评论系统中,基于leancloud的valine不仅简洁,还可以支持匿名留言。leancloud是一个面向个人用户免费的存储系统,valine后台的评论保存就是基于leancloud的。

1
2
3
4
5
6
7
8
9
10
11
12
13
valine:
enable: true
appid: # your leancloud application appid
appkey: # your leancloud application appkey
notify: false # mail notifier , https://github.com/xCss/Valine/wiki
verify: false # Verification code
placeholder: Just go go # comment box placeholder
avatar: wavatar # gravatar style https://valine.js.org/avatar/
guest_info: nick,mail # custom comment header default: nick,mail,link
pageSize: 10 # pagination size
visitors: false
comment_count: false
recordIP: true

为了评论能够及时通过邮箱通知,可以使用 Valine-Admin 来配置。

不蒜子统计网站访问信息

可以通过不蒜子服务来统计网站的访问信息,包括整个网站的UV(Unique Visitor)和PV(Page View),还有每一个post的访问数。

1
2
3
4
5
6
7
8
busuanzi_count:
enable: true
total_visitors: true
total_visitors_icon: user
total_views: true
total_views_icon: eye
post_views: true
post_views_icon: eye

注意这里的post_views和配置文件中leanCloud_visitors冲突,这里只开启了不蒜子的服务。

Next主题进阶优化配置

插入音乐

插入音乐可以直接通过网易云音乐生成外链,也可以使用 hexo-tag-aplayer 插件中 MetingJS的支持。

安装了hexo-tag-aplayer插件之后,在Hexo配置文件中加入‘

1
2
aplayer:
meting: true

接着就可以在文章中使用MetingJS播放器了

1
2
3
4
5
# 歌曲模板
{% meting "3986040" "netease" "song" "theme:#555" "mutex:true" "listmaxheight:340px" "preload:auto" %}

# 歌单模板
{% meting "627070825" "netease" "playlist" "theme:#555" "mutex:true" "listmaxheight:340px" "preload:auto" %}

对于网易云音乐因为版权保护无法生成外链从而获取ID的问题,可以参考hexo在文章插入aplayer音乐播放器

插入视频

插入视频可以直接通过B站生成外链,也可以通过插件 hexo-tag-dplayer

  • 直接用生成外链
1
<iframe src="//player.bilibili.com/player.html?aid=74371709&cid=127218978&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

  • hexo-tag-dplayer

    1
    {% dplayer "url=https://什么什么什么.mp4" "https://封面图.jpg" "api=https://api.prprpr.me/dplayer/" "id=" "loop=false" %}

    要使用弹幕,必须有apiid两项,并且若使用的是官方的 api 地址(即上面的),id 的值不能与这个列表的值一样。id 的值自己随便取,唯一要求就是前面这点。如果唯一要求难倒了你,可以使用这个工具将一段与众不同的文字😂生成一段看起来毫无意义的哈希值,这样看起来是不是好多了。

  • 插入Youtube或者Viemo视频

1
2
{% vimeo video_id %}
{% youtube video_id %}

这里的video_id就是视频分享时生成短链接后面的字符。

数学公式

NexT主题里面已经集成了MathJax和KaTex,配置起来也很方便。这里我们使用MathJax来渲染数学公式。

在主题配置文件中,

1
2
3
4
5
6
7
8
math:
per_page: true # 默认为true,表示每篇文章需要额外地单独启用MathJax
mathjax:
enable: true
mhchem: false

vendors:
mathjax: //cdn.jsdelivr.net/npm/mathjax@2/MathJax.js?config=TeX-AMS-MML_HTMLorMML

Hexo默认的渲染引擎hexo-renderer-marked对MathJax的支持很不好,会出现各种莫名其妙的问题。NexT主题的官方文档也推荐换用其他渲染引擎。推荐换用hexo-renderer-kramed

这里是一个典型的LaTeX公式示例,在markdown中的源代码和现实效果如下:

1
$$\frac{1}{m}\lg C=\frac{1}{n}\left(\sum_{i=1}^n{Y_i+\frac{1}{m}\sum_{i=1}^n{X_i}}\right)$$

关于更多和LaTeX相关的内容,可以参考 LaTeX笔记

添加豆瓣读书/电影

hexo-douban是一个支持引入豆瓣读书和电影的hexo插件,它通过爬取豆瓣用户的对应信息,从而生成对应的html文本。

你可以参考官方README或者 在Hexo博客中加入豆瓣读书页面参考部署。

当然作者所做的界面是没有样式的,我们可以在作者的基础上继续魔改增加自己喜欢的样式,在安装好所需插件后,我们打开目录为hexo/node_modules/hexo-douban/lib/templates/index.css文件,里面是整个阅读界面的 css 样式代码文件,我们可以在其中添加背景图片等样式,比如可以添加如下:

文件位置:hexo/node_modules/hexo-douban/lib/templates/index.css
1
2
3
4
5
6
7
8
.main {
padding-bottom: 150px;
margin-top: 0px;
background-image:url("xxx.jpg");
background-size: cover;
background-attachment: fixed;
background-repeat:no-repeat;
}

修改上面的 url 中地址图片链接就可以新增背景图片了~

文章摘要图片

文章摘要(excerpt)是指每篇文章(post)在页面(page)上显示的那部分内容,也就是 [Read More] 之前的文章内容。由于它会展示在页面,因此在每篇文章的文章摘要中加一张图片,页面看起来就很美观。但是有时候可能会出现一个问题:你想从文章中选一张图片作为文章摘要图片,而这张图片由于写作要求,必须添加在文章的末尾,这样点 [Read More] 查看文章时,这张图片就会重复出现了。咋办?

前提是在主题配置文件中:

1
2
3
4
excerpt_description: false

auto_excerpt:
enable: false

首先加代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{% if is_index %}
{% if post.description and theme.excerpt_description %}
{{ post.description }}
<!--noindex-->
<div class="post-button text-center">
<a class="btn" href="{{ url_for(post.path) }}">
{{ __('post.read_more') }} &raquo;
</a>
</div>
<!--/noindex-->
{% elif post.excerpt %}
{{ post.excerpt }}
+
+ {% if post.image %}
+ <div class="out-img-topic">
+ <img src={{ post.image }} class="img-topic" />
+ </div>
+ {% endif %}
+

为了防止有的图片宽度不够导致风格不够统一,页面不美观,需要在hexo/source/_data/styles.styl中加入:

注意,目前自定义的样式文件在hexo/source目录下,这里需要自己创建_data/styles.styl文件,同时在主题配置文件中修custom_file_path

1
2
3
img.img-topic {
width: 100%;
}

最后编辑有这需求的相关文章时,在Front-matter(文件最上方以---分隔的区域)加上一行:

1
image: url

url即图片的链接地址~

永久性链接

Hexo 默认生成的文章地址路径是 :year/:month/:day/:title/。这种链接对搜索爬虫很不友好,因为它的 url 结构超过了三层,太深了;而且,如果修改了文章的文件名,就相应会修改其路径,无法保证链接的永久性,所以需要进行修改。

这里使用插件 hexo-abbrlink 来生成博客文章的永久链接,可以查看该插件的 GitHub 项目页面。首先需要进行安装:

1
$ sudo npm install hexo-abbrlink --save

然后在站点配置文件中修改 permalink

1
2
3
4
5
-permalink: :year/:month/:day/:title/
+permalink: posts/:abbrlink/
+abbrlink:
+ alg: crc32 #support crc16(default) and crc32
+ rep: hex #support dec(default) and hex

定制回到顶部

Yearito’s Blog 看到的,效果如下:

回到顶部

回到顶部

原理很简单,将 back-to-top 按钮添加图片背景,并添加 CSS3 动效即可。

首先,找到自己喜欢的图片素材放到 source/images 目录下。

你可以点击下方按钮下载本站所使用的小猫上吊素材( 小猫咪这么可爱,当然要多放点孜然啦…)

然后在自定义样式文件hexo/source/styles.styl中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//自定义回到顶部样式
.back-to-top {
right: 60px;
width: 70px; //图片素材宽度
height: 900px; //图片素材高度
top: -900px;
bottom: unset;
transition: all .5s ease-in-out;
background: url("/images/scroll.png");

//隐藏箭头图标
> i {
display: none;
}

&.back-to-top-on {
bottom: unset;
top: 100vh < (900px + 200px) ? calc( 100vh - 900px - 200px ) : 0px;
}
}

刷新浏览器即可预览效果。

定制 sidebar

hexo/source/_data/styles.styl中添加

1
2
3
4
5
6
7
8
9
10
11
12
13
.sidebar {
display: block;
width: 320px;
background-image: url(/images/bk.jpg);
background-size: 320px, 659px;
background-position: center;
background-repeat: no-repeat;
background-color: #f5f5f5 !important;

p, span, a {
color: #080808;
}
}

在images目录下添加背景图片作为sidebar的背景图片。

定制 header

1
2
3
.header {
background: url("/images/header-bk.jpg");
}
1
2
3
.header {
background: url("/images/header-bk.jpg");
}

定制网站背景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
body {
background: url("/images/field.jpg");
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
background-position: center;
}

.main-inner {
width: 75%;
}

.content {
border-radius: 10px;
margin-top: 60px;
padding: 25px;
background:rgba(255, 255, 255, 0.8) none repeat scroll !important;
}

定制字体

开启分享

已运行时间

热门文章页面

Next主题扩展功能

使用hexo-admin在线发布文章

在本地部署hexo-admin

一直想给自己的博客添加一个后台在线编辑的功能,搜了一下发现社区已经有 hexo-admin 这个插件。 hexo-admin 可以将常规的hexo命令(new, deploy等)可视化,并且提供了一个在线的markdown编辑器,使得编写hexo blog脱离了本地开发环境和IDE,从而更加灵活。

要使用这个工具,首先需要安装插件:

1
sudo npm install --save hexo-admin

在客户端机器安装好插件之后,在博客根目录下面使用hexo s -d命令,然后打开http://localhost:4000/admin/进行登录就可以管理后台了。

hexo admin后台

安装好后,还需要设置登录的账号密码,不然谁都可以使用你的后台管理。第一次登录后,进入setting菜单,点击Setup authentification here进入用户名密码设置项,按照提示设置后,把生成的代码添加到blog/_config.xml中,如:

1
2
3
4
5
6
# hexo-admin authentification
admin:
username: username
password_hash: $2a$10$L.XAIqIWgTc5S1zpvV3MEu7/rH34p4Is/nq824smv8EZ3lIPCp1su
secret: my super secret phrase
deployCommand: ./admin_script/hexo_deploy.sh

在blog目录下创建对应的 hexo_deploy.sh 文件

1
2
3
4
$ cd blog;
$ mkdir admin_script;
$ touch admin_script/hexo_deploy.sh
$ chmod +x admin_script/hexo_deploy.sh

文件内容如下

1
2
3
#!/bin/bash
hexo generate
hexo deploy

注意,这里的 password_hash 是你自己的明文密码经过加密后的字符串,但是如果用类似下面的网址: https://bcrypt-generator.com/ 会生成:$2y$10$pJjIxxxxxfMn9U/xxxxxNuuA20kh1eoB7vZxxxxx/7WpeV7IOxxxx类似的加密串,但是运行会报invalid salt revision错误,其原因是:

1
2
3
4
5
6
7
8
9
10
11
$ cat node_modules/hexo-admin/www/bundle.js | head -4851 | tail -10
if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
throw "Invalid salt version";
if (salt.charAt(2) == '$')
off = 3;
else {
minor = salt.charAt(2);
if (minor != 'a' || salt.charAt(3) != '$')
throw "Invalid salt revision";
off = 4;
}

需要版本号是2a的加密方式,因此只能用python自己写了:
https://pypi.org/project/bcrypt/3.1.0/

1
2
3
>>> hashed = bcrypt.hashpw(password, bcrypt.gensalt(prefix=b"2a"))
>>> print(hashed)
b'$2a$12$PAoJr3USOBxxxxxxxxxxxxxxV/.h.QNbh/6q.xxxxxxxxxxxxxxxxcDcJ.'

经过这些设置之后,进入后台,就可以在线创作博客了。admin的后台有一个deploy的按钮,点击这个按钮就会执行hexo_deploy.sh 的脚本。该脚本会将markdown文件生成静态网页,如果用nginx配置去访问静态网页,速度就会快很多。

在服务器端部署hexo-admin

上面的部署有一个问题,就是我是想让我的在线博客具有后台编辑的功能,而不是必须在我本地启动hexo。那么要解决这个问题,必须要在服务器端运行hexo server的进程。

在之前的部署中

  • 我们都是在服务器端只是部署了nginx,在客户端机器安装了hexo的环境,所有hexo的配置都是在客户端机器上的。
  • 每次在客户端更新了hexo源文件后,在客户端环境执行hexo generate && hexo deploy将生成的public目录下的网站源文件通过git传到服务端的git服务器目录。
  • 服务器端的git服务器通过git hooks将对应的文件复制到nginx对应的root目录

要在服务端运行hexo server的命令,我们需要在服务端有hexo server运行的环境。这个环境其实也就是安装了所有插件之后的blog根目录。好在我们已经将blog目录通过git做了版本控制,这里的版本控制不仅仅监控发布post的版本,还监控网站主题各种配置的版本。

之前我每次更新后会将这个push到github自己的一个私人目录下。现在可以push到自己的git服务器,然后通过 git hooks 自动更新到某个固定的目录。通过 hexo-admin 后台编辑发布新文章会更新这个blog的目录,本地的blog可以通过git fetch 拉取远端的最新情况。

说干就干,具体操作如下

服务器端创建新的blog的repo

在前面的操作中我们配置Git服务,这个repo是存放的是generate出来的网站源文件,现在我们还是在git用户的repositories目录下新创建一个repo,不过这个repo里面存放的是blog的源文件,通过这个blog源文件,执行hexo generate的命令可以生成网站的源文件。

1
2
3
4
5
6
$ cd /home/git/repositories
$ git init --bare hexo.git
$ cat .ssh/id_rsa.pub >> .ssh/authorized_keys # 添加ssh权限
$ cd hexo
$ sudo npm install --production
$ hexo generate

修改Nginx的配置文件,是的其root地址指向hexo产生的目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 80 default_server;
listen [::]:80 default_server;

server_name houmin.cc;

root /home/git/hexo/public;
index index.html index.htm;

location / {
error_page 404 /404/;
}

location /admin {
proxy_pass http://houmin.cc:50003/admin;
}
}

重启nginx服务,应该就能够看到网站能够再次运行了

使用pm2保持hexo server一直在服务器后台运行

pm2是一个专门为NodeJS开发的进程管理工具,支持管理node进程,查看node进程的状态,也支持性能监控和进程守护。因为使用 hexo server -d & 在一段时间后会停止hexo,此时无法打开后台,所以我们采用pm2接管hexo进程。

在服务器端,

1
sudo npm install -g pm2

在服务器端博客的根目录下创建一个hexo_run.js的文件,内容如下

1
2
3
4
5
6
7
8
9
const { exec  } = require('child_process')
exec('hexo server -p 50003 -d',(error, stdout, stderr) => {
if(error){
console.log('exec error: ${error}')
return
}
console.log('stdout: ${stdout}');
console.log('stderr: ${stderr}');
})

运行开启命令

1
pm2 start hexo_run.js

附上一个hexo重启脚本,restart_hexo.sh, 需要重启刷新的时候执行 source restart_hexo.sh即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

PROCESS=`ps -ef|grep hexo|grep -v grep|grep -v PPID|awk '{ print $2 }'`
PROC_NAME="pm2"
for i in $PROCESS
do
echo "Kill the $1 process [ $i ]"
kill -9 $i
done
hexo clean #清除数据
hexo generate #生成静态文件public文件夹
ProcNumber=`ps -ef |grep -w $PROC_NAME|grep -v grep|wc -l`
if [ $ProcNumber -le 0 ];then
pm2 start hexo_run.js
else
pm2 restart hexo_run.js
fi

service nginx restart

注意,我们可以看到hexo_run.js里面通过让hexo server监听在50003的端口,然后用pm2管理这个进程。在nginx的配置里面,用户通过http://houmin.cc/admin的请求,会被nginx重定向到hexo server那里。所以,你需要在云服务厂商那里配置安全组策略,开放这里的50003端口,使得用户可以访问对应的后台。

在客户端编辑博客

可以看到我们现在可以在线编辑博客,那么如果我们想在客户端机器上本地编辑博客怎么办呢?

这里需要修改一下站点的配置文件

1
2
3
4
deploy:
type: git
repo: git@13.250.11.186:/home/git/repositories/blog.git
branch: master

这里每次更新之后还是可以执行hexo generate && hexo deploy去更新博客,只是在blog的git hooks需要修改为

1
2
#!/bin/bash
git --work-tree=/home/git/hexo/public --git-dir=/home/git/repositories/blog.git checkout -f

注意这里的work-tree改成了新的目录

相册管理

对于相册,在自己博客上期待实现的效果与豆瓣相册类似,具体如下

  • 主界面
    • 分类相册
    • 自定义相册名
    • 自定义封面
    • 自动裁剪封面为等尺寸
  • 分类相册界面
    • 三等分列
    • 按图片原长宽比平铺
    • 点击看大图
    • 本地图片源/图床外链均可
    • 与文章插图格式保持统一
  • 其他
    • 每张图片都可以有对应的文字描述
    • 游客可以为图片添加评论
    • 相册里面也可以插入视频

2019.12.05更新:终于填坑把相册这一块给补上了,参考 Hexo NexT主题添加多级相册功能

项目管理

资源库

开启HTTPS

现在个人博客开启HTTPS可以看到 cloudflareletsencrypt 两种方案,这里的是 letsencrypt 的方案,参考博客 教你快速撸一个免费HTTPS证书

安装 certbot

Certbot可以用于管理(申请、更新、配置、撤销和删除等)Let’s Encrypt证书。这里安装的是带nginx插件的certbot:

1
2
3
4
5
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:certbot/certbot
sudo apt-get update
sudo apt-get install -y python-certbot-nginx

申请证书

使用certbot命令为houmin.cc申请HTTPS证书。—nginx选项表示Web服务器为nginx,-d选项指定域名,-n选项表示非交互式运行命令。若去除-n选项,则终端会提醒你选择是否将http请求重定向为https请求。

1
certbot --nginx -d houmin.cc

证书申请成功之后,会看到以下信息。Let’s Encrypt证书的有效期只有3个月,但是Certbot会通过Cron和systemd timer自动更新证书,证书的时效性不用担心。

1
2
3
4
5
6
7
8
9
10
11
12
13
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/houmin.cc/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/houmin.cc/privkey.pem
Your cert will expire on 2020-03-15. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

当前的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
server {

server_name houmin.cc;

root /home/git/hexo/public;
index index.html index.htm;

location / {
error_page 404 /404/;
}

location /admin {
proxy_pass http://houmin.cc:50003/admin;
}

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain text/css text/xml application/javescript application/json image/jpeg image/gif image/png;
gzip_vary on;

listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/houmin.cc/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/houmin.cc/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

博客写作进阶

Note标签使用

1
2
3
{% note default %}
默认形式的类别
{% endnote %}

默认形式的类别

1
2
3
{% note primary %}
首要类型形式
{% endnote %}`

首要类型形式

1
2
3
{% note info %}
info形式
{% endnote %}

info形式

1
2
3
{% note success %}
首要类型形式
{% endnote %}

success形式

1
2
3
{% note warning %}
warning形式
{% endnote %}

warning形式

1
2
3
{% note danger %}
danger形式
{% endnote %}

danger形式

文本居中引用

1
2
3
4
5
6
{% cq %}
人生乃是一面镜子,
从镜子里认识自己,
我要称之为头等大事,
也只是我们追求的目的!
{% endcq %}

人生乃是一面镜子,
从镜子里认识自己,
我要称之为头等大事,
也只是我们追求的目的!

Tabs标签

1
2
3
4
5
6
7
8
9
10
11
{% tabs 选项卡, 2 %}
<!-- tab -->
**这是选项卡 1**
<!-- endtab -->
<!-- tab -->
**这是选项卡 2**
<!-- endtab -->
<!-- tab -->
**这是选项卡 3**
<!-- endtab -->
{% endtabs %}

这是选项卡 1

这是选项卡 2

这是选项卡 3

插入 PDF

next/_config.yml
1
2
3
4
pdf:
enable: true
# Default height
height: 500px

使用方法

1
2
3
4
{% pdf url [height] %}

[url] : Relative path to PDF file.
[height] : Optional. Height of the PDF display element, e.g. 800px.

Label

1
2
3
4
5
6
{% label [class]@Text %}

[class] : default | primary | success | info | warning | danger.
'@Text' can be specified with or without space
E.g. 'success @text' similar to 'success@text'.
If not specified, default class will be selected.
1
2
3
4
5
Lorem {% label @ipsum %} {% label primary@dolor sit %} amet, consectetur {% label success@adipiscing elit, %} sed {% label info@do eiusmod %} tempor incididunt ut labore et dolore magna aliqua.

Ut enim *{% label warning @ad %}* minim veniam, quis **{% label danger@nostrud %}** exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate ~~{% label default @velit %}~~ <mark>esse</mark> cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

博客推广及优化

添加robots.txt

robots.txt是搜索引擎蜘蛛协议,告诉引擎哪些要收录,哪些禁止收录。
source文件夹下新建 robots.txt,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
User-agent: *
Allow: /
Allow: /archives/
Allow: /categories/
Allow: /tags/
Allow: /about/
Allow: /posts/

Disallow: /assets/
Disallow: /js/
Disallow: /css/
Disallow: /lib/

Sitemap: http://www.houmin.cc/sitemap.xml
Sitemap: http://www.houmin.cc/baidusitemap.xml

URL持久化

大家知道 hexo 默认的链接是 http://xxx.yy.com/2018/07/14/hello-world 这种类型的,这源于站点目录下的配置 _config.yml 里的配置 :permalink: :year/:month/:day/:title/,这种默认配置的缺点就是一般文件名是中文,导致 url 链接里有中文出现,同时多层目录也不利于SEO。

hexo-abbrlink这个插件,猜测是根据时间点算出的最终链接,这样就确保了博文链接的唯一化,只要不修改 md 文件的abbrlink的值, url 就永久不会改变。如此 md 文件名和文件内容也可以随便改了。后面的层级更短,这样也有利于 SEO 优化。

安装:

1
npm install hexo-abbrlink --save

配置:
站点配置文件里:
1
2
3
4
permalink: post/:abbrlink/
abbrlink:
alg: crc32 # 算法:crc16(default) and crc32
rep: hex # 进制:dec(default) and hex

百度蜘蛛抓取网页的规则: 对于蜘蛛说网页权重越高、信用度越高抓取越频繁,例如网站的首页和内页。蜘蛛先抓取网站的首页,因为首页权重更高,并且大部分的链接都是指向首页。然后通过首页抓取网站的内页,并不是所有内页蜘蛛都会去抓取。

搜索引擎认为对于一般的中小型站点,3层足够承受所有的内容了,所以蜘蛛经常抓取的内容是前三层,而超过三层的内容蜘蛛认为那些内容并不重要,所以不经常爬取。出于这个原因所以permalink后面跟着的最好不要超过2个斜杠。

添加nofollow标签

nofollow 标签是由谷歌领头创新的一个反垃圾链接的标签,并被百度、yahoo 等各大搜索引擎广泛支持,引用 nofollow 标签的目的是:用于指示搜索引擎不要追踪(即抓取)网页上的带有 nofollow 属性的任何出站链接,以减少垃圾链接的分散网站权重。
这里推荐 hexo-autonofollow 插件来解决。

安装:

1
npm install hexo-autonofollow  --save

配置:
在站点配置文件中添加以下代码:
1
2
3
4
5
nofollow:
enable: true
exclude: # 例外的链接,可将友情链接放置此处
- 你自己的站点地址
- 友链地址

搜索引擎收录

参考博客 百度录入

网站加速

Nginx gzip压缩

参考 Nginx gzip压缩

利用gulp压缩代码

参考 gulp压缩

修改默认Google字体库

对象存储存放图片资源

图床替换之后,可以通过sed命令全局替换图片链接

多主机同步源码

参考文章