Hexo 入门到入土👨‍💻

前言

Hexo 是一个快速、简洁且高效的博客框架,许多人使用它来建立一个博客网站。但是由于 Hexo 官方网站的教程并没有涉及到主题配置及自定义,甚至有一些 Hexo 主题连官方文档都没有,导致使用者需要阅读那些网上良莠不齐的教程。而本文档将提供一站式的 Hexo 教程。 @Easy Hexo

Hexo 有什么优点?

  • 完全免费*
  • 静态网页
  • 使用方便

*:当然,这并不说明整个博客都是免费的。你可能会去购买域名等等。

本文档适用人群

  • 程序员
  • 对创作、编码感兴趣的学生
  • 希望可以定期整理笔记的 OIer/ACMer

学完本文后

  • :sunglasses: 使用 Hexo 建立一个博客网站
  • :balloon: 修改 Hexo 现有主题
  • :gem: 自制一个 Hexo 主题

初衷

当时我们发现用 Hexo 的同学们普遍都是以下人群:

  1. OIer / ACMer
  2. 程序员 / 程序热爱者
  3. ……

他们大部分都是因为 没有前端基础 / 买不起服务器 / 不喜欢 CSDN、博客园这类平台 才使用 Hexo 的。

Hexo 的优点吸引了他们,而 Hexo 也有以下缺点:

  1. 官方文档不够完整,没有配置主题相关的内容
  2. 使用较麻烦,经常报错且难以排错

认识 Hexo

Hexo 是一个快速、简洁且高效的博客框架,可以让你快速建立一个博客。

快速

Hexo 使用 Node.js 编写。得益于 Node.js,使得 Hexo 生成上百个页面游刃有余。

支持 Markdown

Hexo 支持 GFM (GitHub Flavored Markdown) 的大部分功能。如果你不喜欢 Markdown ,你还可以换一个 Hexo 渲染插件。

部署方便

只需要一条指令就可以部署到 GitHub Pages、Heroku、Coding Pages 等其他网站。

插件丰富

Hexo 有许多插件,可以进行各种操作。

学习 Hexo 之前,你需要有:

  • Node.js 基本知识
  • Git 基本知识
  • Markdown 基本知识
  • Html、css、JavaScript 基本知识
  • ······

当然了,你可别被吓跑了。除了 Markdown ,其他都不用熟练掌握(事实上如果你不注意排版连 Markdown 都不用掌握,但最好还是学学吧)。如果你完全不会以上划线部分的知识,也没关系。只是简单地建个可以发文章的博客就好了。如果你要更上一层楼,那么以上被划掉的知识就是必备的啦~

安装 Hexo

在安装 Hexo 之前,你需要安装以下两个工具:

如果您已经安装好以上两个工具,可以直接跳转至 安装 Hexo

安装 Git

  • Windows:下载并安装 git.
  • Mac:使用 Homebrew, MacPortsbrew install git;或下载 安装程序 安装。
  • Linux (Ubuntu, Debian):sudo apt-get install git-core
  • Linux (Fedora, Red Hat, CentOS):sudo yum install git-core
  • Linux (Arch 系列):sudo pacman -S git

:::tip 提醒
由于墙的原因,从上面的链接下载 git for windows 最好挂上一个代理,否则下载速度十分缓慢。也可以参考这个页面,收录了存储于百度云的下载地址。
:::

:::tip 提醒
如果你是 CentOS 服务器上的,可以直接使用 HexoOneClickInstallation 这个脚本快速安装 Hexo。
:::

安装 Node.js

安装 Node.js 的最佳方式是使用 nvm

cURL:

COPY$ curl https://raw.github.com/creationix/nvm/v0.33.11/install.sh | sh

Wget:

COPY$ wget -qO- https://raw.github.com/creationix/nvm/v0.33.11/install.sh | sh

安装完成后,重启终端并执行下列命令即可安装 Node.js。

COPY$ nvm install stable

或者您也可以下载 安装程序 来安装。

:::tip 提醒
在中国大陆由于某些众所周知的网络原因,推荐使用淘宝 NPM 镜像

scriptCOPYnpm install -g cnpm --registry=https://registry.npm.taobao.org

使用 cnpm install 来代替所有 npm install 指令。
:::

安装 Hexo

此处更倾向推荐查看Hexo 官方文档

安装好后,即可使用 npm 完成 Hexo 的安装。

COPY$ npm install -g hexo-cli

部署 Hexo

部署到 GitHub

准备工作

  1. 如果没有账号,请点此前往 GitHub 注册一个 GitHub 账号。
  2. 新建一个公开仓库,仓库名格式为 your_username.github.io 例如你的 GitHub 用户名是 easyhexo,那么你的仓库地址名称就应该是 easyhexo.github.io
  3. 创建完成后记下该仓库的 HTTPS/SSH 地址,一般格式为 https://github.com/your_username/your_reponame.git 在下一步会用到。

安装部署插件

COPY$ npm install hexo-deployer-git --save
$ npm install hexo-server --save

配置 Git

如果你只是安装好了 Git 但没有配置过你的 Git ,那么现在需要做的第一件事情就是设置你的 Git 用户名和邮箱。
在 Git Bash 中执行以下两条命令配置你的用户名和邮箱,这里建议用户名和邮箱与你的 GitHub 用户名和邮箱保持一致。

COPY$ git config --global user.name "Your_user_name"
$ git config --global user.email [email protected]

:::tip 提醒
每次 Git 提交时都会附带这两条信息,用于记录是谁提交的更新,并且会随更新内容一起被记录到历史记录中。简单说,是用来标记的你的身份的~
:::

配置站点 _config.yml 文件

COPYdeploy:
  type: git # 类型填git
  repo: <repository url> # 你的Github仓库地址
  branch: master # 分支名称。默认填写 master 如果您使用的是 GitHub ,程序会尝试自动检测。
  message: # 提交信息可以自定义,不填的则默认为提交时间

发布到 GitHub

在本地的 Hexo 站点根目录下,执行如下命令即可部署到 GitHub Pages 上。

COPY$ hexo clean && hexo d -g

:::tip 提醒
如果是第一次使用,会弹出一个登录框,需要登录你的 GitHub 账号。
:::

自定义域名

  1. 如果你拥有个人域名,请用 A 记录解析到以下 IP 中的任意一个。如果使用 CNAME 请解析到你的 GitHub 仓库名称。
COPY185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153

参考表格

记录类型 主机记录 解析路线 记录值 MAX 优先级 TTL(秒)
A @ 默认 185.199.110.153 600
CNAME @ 默认 GitHub 博客仓库名称 600
  1. 打开仓库设置,找到 GitHub Pages 项目,修改 Custom domain 选项的值为你的自定义域名(不带 http 等前缀)
  2. 勾选 Custom domain 选项下的 Enforce HTTPS 选项,强制开启 Https 。如果遇到 Enforce HTTPS 选项无法打开,可以稍等一会儿再尝试。

:::tip 提醒
同时需要在本地的 source 目录新建一个 CNAME 文件,内容为你的自定义域名(不带 http 等前缀)。否则无法使用自定义域名功能(hexo d 生成的文件没有 CNAME 文件,导致仓库的自定域名设置失效)
:::

部署到 Netlify

Netlify 是一个可以部署静态网站的平台,也可以从 GitHub/GitLab/Bitbucket 的项目中快速构建你的网站。相比 GitHub Pages 更加专业、便捷,即使在国内的访问速度也不错,百度也能收录。

准备工作

:::tip 提醒
准备工作和部署到 GitHub 一样。
:::

  1. 如果没有账号,请点此前往 GitHub 注册一个 GitHub 账号。
  2. 新建一个公开仓库,仓库名格式为 your_username.github.io 例如你的 GitHub 用户名是 easyhexo,那么你的仓库地址名称就应该是 easyhexo.github.io
  3. 创建完成后记下该仓库的 HTTPS/SSH 地址,一般格式为 https://github.com/your_username/your_reponame.git 在下一步会用到。

配置 Git

:::tip 提醒
配置 Git 也和部署到 GitHub 一样。
:::

如果你只是安装好了 Git 但没有配置过你的 Git ,那么现在需要做的第一件事情就是设置你的 Git 用户名和邮箱。
在 Git Bash 中执行以下两条命令配置你的用户名和邮箱,这里建议用户名和邮箱与你的 GitHub 用户名和邮箱保持一致。

COPY$ git config --global user.name "Your_user_name"
$ git config --global user.email [email protected]

:::tip 提醒
每次 Git 提交时都会附带这两条信息,用于记录是谁提交的更新,并且会随更新内容一起被记录到历史记录中。简单说,是用来标记的你的身份的~
:::

配置本地和远程仓库

在博客根目录打开终端并执行以下命令:

COPYgit init
git add .
git commit -m ":tada: Init repo"
git remote add origin [email protected]:你的名字/你的项目名字.git
git push -u origin master

这样就将你的 Hexo 博客 push 上 GitHub 仓库了。以后更新博客只需要 git push origin master 即可。

配置 Netlify

  1. 首先打开 Netlify 官网,用 GitHub 帐号登录。
  2. 点击 New site from Git ,进入 Create a new site 页面。
  3. Connect to Git provider 页面,选择 GitHub。
  4. Pick a repository 页面,选择你刚刚创建的博客存储库。
  5. 最后一步 Build options, and deploy!,Netlify 会检测到是 Hexo 项目,自动配置好了。点击 Deploy site 按钮即可。
    build-options

最后出现如下界面:

deploy-done

可以看到 Netlify 自动分配了一个域名,在这个网站中是 https://nifty-noyce-b98546.netlify.com

如果你有自己的域名并想要绑定它,请点击 Set up a custom domain 链接。这里不再赘述,详细步骤请见 Netlify Docs: custom-domains

关于 HTTPS 的设置,Netlify Docs 中也有详细教程。请自行阅读。

部署到 CODING

准备工作

::: details CODING or dev.tencent.com?
CODING = dev.tencent.com

2019 年 12 月 25 日,CODING 个人版与腾讯云开发者平台升级至全新 CODING。也就是说,这两个平台回合并成 CODING 了。

::: right
致 CODING 个人版/腾讯云开发者 平台用户的一封信
:::

  1. 如果没有账号,请点此前往 CODING 注册 CODING 账号。
  2. 新建一个公开仓库,仓库名格式为 your_username.coding.me 例如你的 CODING 用户名(username)是 easyhexo,那么你的仓库名称就应该是 easyhexo.coding.me
  3. 创建完成后记下该仓库的 HTTPS/SSH 地址 一般格式为 https://coding.net/your_username/your_reponame.git 在下一步会用到。
  4. 如果您没有配置 Githexo-deployer-git 请参阅前文配置方法配置。

配置站点 _config.yml 文件

COPYdeploy:
  type: git # 类型填 git
  repo:
    github: <github repository url> # 你的 GitHub 仓库地址
    coding: <coding repository url> # 你的 coding 仓库地址
  branch: master # 默认填写 master。
  message: # 提交信息可以自定义,不填的则默认为提交时间

发布到 CODING

在本地 Hexo 站点根目录下,执行如下命令即可部署到 CODING Pages 上。

COPY$ hexo clean && hexo d -g

:::tip 提醒
如果是第一次使用,会弹出一个登录框,需要登陆你的 CODING 账号。
:::

自定义域名

  1. 如果你拥有个人域名,请添加 CNAME 记录。
  2. 绑定前请在域名 DNS 设置中添加一条 CNAME 记录指向 xxxx.coding.me。将 @ 和 www 记录都解析到这个即可。

参考表格

记录类型 主机记录 解析路线 记录值 MAX 优先级 TTL(秒)
CNAME www 默认 xxxx.coding.me 600
CNAME @ 默认 xxxx.coding.me 600
  1. 打开仓库设置,找到 代码-Pages 服务,在绑定新域名下的文本框内输入你的自定义域名(不带 http 等前缀)。
  2. 勾选 强制 HTTPS 访问。

:::tip 提醒
出于 SEO 的考虑,我们建议您绑定一个 www 域名即可,如果您使用的域名 DNS 解析服务不支持添加 CNAME 记录,建议更换 Nameservers 到其他支持该功能的域名提供商(如 腾讯云)。如果遇到自定义域名失效,请参照前文 GitHub 配置方案解决。
:::

详细内容请参阅 CODING 官方文档

部署到 CentOS Servers

预先准备

  • 确保你的 PC 已经安装好 Hexo 主程序的并且生成站点文件夹。安装 Hexo,请参阅安装 Hexo
  • 一台搭载 CentOS 7.4 64bit 的 ECS 服务器实例,其他 Linux 系统也可以
  • 你至少应该掌握一丢丢的 Linux 命令

安装部署插件

COPY$ npm install hexo-deployer-git --save
$ npm install hexo-server --save

服务器环境配置

更新服务器的软件包

COPYyum -y update

安装 Git

COPYyum install git -y

新建 Git 用户

COPYuseradd -m git

设置 gituser 的密码

COPYpasswd git

配置 SSH 免密登陆

我们在使用 SSH 访问服务器时每一次连接都需要验证相应用户的密码,十分繁琐,所以我们通过一组密匙来进行授权访问。
Git Bash 中使用 ssh-keygen 命令在你的电脑上生成一组密匙,这个过程中 ssh-keygen 会确认密钥的存储位置( Windows 下默认是 c:users/username/.ssh/id_rsa),然后它会要求你输入两次密钥口令。如果你不想在使用密钥时输入口令,将其留空。

COPY$ ssh-keygen

使用 ssh-copy-id -i 命令将公钥也就是 id_rsa.pub 添加到服务器上。这个过程中需要验证你所添加的用户的密码,如果你的服务器上存在多个用户,你需要逐一添加。添加完成后可以通过 ssh your_user_name@HostIP 命令来验证是否添加成功。

COPY$ ssh-copy-id -i ~/.ssh/id_rsa.pub your_user_name@HostIP  //添加公钥
$ ssh your_user_name@HostIP   //验证是否添加成功

禁止 Git 用户 Shell 登陆权限

出于安全考虑,禁用 Git 用户的 shell 权限(必须先验证是否可以免密码登陆,可以后再禁用 shell 权限,否则无法通过 ssh-copy-id -i 添加 SSH 公钥),使用 vim /etc/passwd 命令修改 ~/etc/ 下的 passwa 文件

COPY-  git:x:1001:1001:,,,:/home/git:/bin/bash
+  git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

SSH 免密登陆无效问题排查

检查 /etc/ssh/ 目录下的 sshd_config 文件,确认以下关键选项是否正常

COPYRSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys
#GSSAPIAuthentication yes
#GSSAPICleanupCredentials yes

若还是不能正常工作,则检查用户权限和组权限

COPYchmod 0755 /home/your_user_name
chmod 700 /home/your_user_name/.ssh
chmod 600 /home/your_user_name/.ssh/authorized_keys

关于 SSH 的更多问题可查阅这里

初始化 Git 仓库

新建 /var/repo 目录,并在该目录下,使用 git init --bare 创建一个名为 blog.git 裸仓库,并改变该目录的所有者为 git 用户。

裸仓库可以直接作为服务器仓库供各开发者 push、pull 数据,实现数据共享和同步,不保存文件,只保存历史提交的版本信息。

COPYmkdir -p /var/repo    //新建 var/repo 目录
cd /var/repo          //进入该目录
git init --bare blog.git   //新建一个裸仓库
chown -R git:git blog.git

配置 Git Hooks

使用 vim 命令在 /var/repo/blog.git/hooks 目录下创建 post-receive 文件

COPYvim /var/repo/blog.git/hooks/post-receive

并且在 post-receive 文件中写入以下内容

COPY#!/bin/sh
git --work-tree=/home/www/hexo --git-dir=/var/repo/blog.git checkout -f

提升 post-receive 的可执行权限

COPYchmod +x /var/repo/blog.git/hooks/post-receive

安装 Nginx

Nginx 是一个高性能的 HTTP 和反向代理服务,也是一个 IMAP/POP3/SMTP 服务。外网用户访问服务器的 Web 服务由 Nginx 提供,Nginx 需要配置静态资源的路径信息才能通过 url 正确访问到服务器上的静态资源。

在安装之前我们先创建用于存放静态资源的目录 /home/www/hexo ,并更改其所有者,稍后将其设置为 Nginx 的默认静态资源目录。

COPYmkdir -p /home/www/hexo      //创建目录
chown -R git:git /home/www/hexo   //更改目录所有者
yum install nginx -y   //安装Nginx

配置静态服务器访问路径

修改 Nginx 默认静态资源路径,打开 Nginx 的默认配置文件 /etc/nginx/nginx.conf ,将默认的 root /usr/share/nginx/html; 修改为: root /home/www/hexo; 如下所示。

COPY    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
-       root         /data/www;
+       root         /home/www/hexo;

        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

如果你拥有 SSL,TSL 证书,需要配置 HTTPS 访问或者添加 HTTP 强制转换 HTTPS 访问功能,请参照以下代码进行配置。

COPYserver {
        listen       80 default_server;
        listen       [::]:80 default_server;

        return 301 https://liujunzhou.top$request_uri; # 使用301重定向
 }

# Settings for a TLS enabled server.

server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  liujunzhou.top; #你的域名
        root         /home/www/hexo; # Nginx 静态资源存放路径

        ssl_certificate "/etc/pki/tls/certs/CA.crt";
        ssl_certificate_key "/etc/pki/tls/certs/CA.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照此协议配置
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照此套件配置
        ssl_prefer_server_ciphers on;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

配置_config.yml文件

_config.yml 文件中设置 deploy 选项

COPY# Deployment
deploy:
  - type: git # 类型填git
    repo: your_user_name@HostIP:/var/repo/blog.git
    branch: master
    message:

发布站点

在你的 Hexo 站点根目录下,执行如下命令即可发布你的站点到服务器上。

COPY$ hexo clean && hexo d -g

其他问题

Hooks 失效

如果部署成功,但是 /home/www/hexo 目录的资源文件并未更新,请检查 post-receive 是否有执行权限,以及 /home/www/hexo 文件所有者是否为 Git 用户,以及是否具有读写权限。

COPYchown -R git:git /var/repo/blog.git  //更改blog.git目录的所有者
chmod +x /var/repo/blog.git/hooks/post-receive   //提升post-receive执行权
chown -R git:git /home/www/hexo   //或者chmod 755 /home/www/hexo 确保hexo文件夹为空

部署后,部分页面 404

部分情况下,在初次部署之后,部分文章或者页面路径大小如果更改了,会导致新部署上去的页面出现 404 错误。
这是由于 Git 没有区分大小写导致的文件路径错误。修改 hexo根目录/.deploy_git/.git/ 下的 config 文件

COPY[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = false
    symlinks = false
-    ignorecase = true
+   ignorecase = false

[branch “master”]

remote = ueser_name@HostIP:/var/repo/blog.git merge = refs/heads/master

持续集成

:::tip
利用 Travis CI 将 Hexo 持续集成部署到 GitHub Pages. 👷

使用 CI 也可以直接在 GitHub 上面在线编辑文章!

(如果觉得没必要,可略过。)
:::

什么是持续集成?

持续集成(英语:Continuous integration,缩写 CI)是一种软件工程流程,是将所有软件工程师对于软件的工作副本持续集成到共享主线(mainline)的一种举措。

简单来说,我们通过持续集成,能够简化 Hexo 发布博客的步骤,即:将清除缓存 hexo clean,生成静态文件 hexo generate 和部署到 GitHub Pages hexo deploy 这些步骤通过持续集成工具来帮助我们自动执行。

这样我们在本地对博客文件进行修改、新增博文内容或者新增博客文章,只需要通过 git 推送到 GitHub 仓库之后,持续集成工具就可以帮助我们在线构建博客静态文件并直接部署到 GitHub Pages。这之后,我们发布博客内容就不需要本地三步走了。

同时,使用 CI 也可以让我们直接在 GitHub 上面随时随地在线编辑文章!

👷 本章我们所利用的持续集成平台是 Travis CI.

注册 Travis CI 账号,绑定 GitHub 账户

首先,我们到 Travis CI 官网,用自己的 GitHub 账户直接关联登录,并允许 Travis CI 查看自己的公有仓库。

然后我们到 Travis CI 账户页面 开启我们的博客仓库。如图。

img

配置文件

配置本地和远程仓库

:::warning 警告
由于 GitHub Pages 的限制,每个人的默认博客仓库 xxx.github.io 只允许将静态文件托管在仓库的 master 分支。
:::

为了方便下面步骤的进行,我们进行这样的配置:

  • 备份博客源文件
  • 在本地仓库创建 hexo 分支
COPY# 克隆项目到本地
git clone https://github.com/xxx/xxx.github.io.git
# 创建并切换到 hexo 分支
git checkout -b hexo
  hexo

分支保存博客项目的源代码

  • hexo 分支下的文件除 .git 目录外全部删除
  • 将博客源码文件拷贝到该目录下,并提交 Commit 到 hexo 分支.
  • 将本地 hexo 分支内容提交到 GitHub 远程仓库
COPY# 提交本地 hexo 分支到远程仓库的 hexo 分支
git push origin hexo:hexo

经过这样的配置,我们博客仓库项目文件应该是这样的:

  • hexo 分支保存博客项目的源代码
  • master 分支保持项目的静态文件(即 public 文件夹下的内容)

配置持续集成文件

.travis.yml 是 Travis CI 的部署配置文件,Travis CI 部署时会自动读取我们每次 Commit 中是否包含 .travis.yml,有此文件才会开始部署。

创建 .travis.yml 配置文件

在博客项目源代码分支下(hexo 分支)创建文件 .travis.yml,并添加如下内容:

COPYlanguage: node_js # 编译语言、环境

sudo: required # 需要管理员权限

dist: xenial # 指定 CI 系统版本为 Ubuntu16.04 LTS

node_js: stable #Node.js 版本

branches:
  only:
    - hexo # 只有 hexo 分支检出更改才触发 CI

before_install: 
  - export TZ='Asia/Shanghai' #配置时区为东八区 UTC+8
  - npm install hexo-cli # 安装 hexo
#  - sudo apt-get install libpng16-dev # 安装 libpng16-dev CI 编译出现相关报错时请取消注释

install:
  - npm install # 安装依赖

script: # 执行脚本,清除缓存,生成静态文件
  - hexo clean
  - hexo generate

deploy:
  provider: pages
  skip_cleanup: true # 跳过清理
  local_dir: public # 需要推送到 GitHub 的静态文件目录 
  name: $GIT_NAME # 用户名变量
  email: $GIT_EMAIL # 用户邮箱变量
  github_token: $GITHUB_TOKEN # GitHub Token 变量
  keep-history: true # 保持推送记录,以增量提交的方式
  target-branch: master # 推送的目标分支 local_dir->>master 分支
  on:
    branch: hexo # 工作分支

:::warning 警告

  • 其他文档可能提到了利用 hexo-deployer-git 进行部署,但是由于 Travis CI 本身支持直接部署到 GitHub Pages 的工具,因此无需另行安装 hexo-deployer-git 了;
  • 其他文档也可能提到在 .travis.yml 中加入如下内容,来缓存 node_modules 下的内容,从而加快编译速度。但是经过我的尝试,node_modules 经常会由于没有及时更新,在添加其他组件之后出现「博客生成静态文件步骤」失败的情况,因此建议不进行缓存处理。
COPYcache:
  directories:
    - node_modules

:::

在 Travis CI 中配置变量

在配置文件中我们使用了三个变量:

  • $GIT_NAMEgit 用户名
  • $GIT_EMAILgit 用户邮箱
  • $GITHUB_TOKEN:GitHub 通行证 (token) 字符串

其中前两项可以通过在本地终端中这样查看:

COPYgit config --global user.name
git config --global user.email

如下图所示:

img

最后一项 GitHub 通行证 (token) 我们在 GitHub 中进行申请:

  • 访问 GitHub 账户设置 > Tokens
  • 生成新 Token: Generate new token
  • 填入 Token 描述,并给予 Token 第一项 repo 的全部权限
img
  • 将生成的 Token 复制,保存(生成 Token 的页面只有一次机会看见,请保存妥当。)

在 Travis CI 仓库配置中,将三个变量填入设置(位于 Settings > Environment Variables 处并保存:

img

自动部署

经过以上步骤的配置,发布博客的命令就变更为:

COPY# 切换到 hexo 分支
git checkout hexo

# 提交新博文
git add .
git commit -m "Publish new post."

# 推送到远程仓库
git push

这样,在每次我们将博客的源文件通过 git 推送到 GitHub 的 hexo 分支上后,Travis CI 就会自动检测并主动开始构建我们的博客静态文件,并自动部署到 GitHub Pages 中。

除了方便部署,我们同时还在 GitHub 上面成功开启了我们博客源代码的备份,一箭双雕。👷

主题使用与配置

本章将会让你学会使用与配置 Hexo 主题,是一个比较重要的部分。

在本章节中,收录的主题有:

还有许多优秀主题由于各种原因没有收录

插件使用与配置

本节主要讲解如何安装和使用 Hexo 插件。目前有以下插件的文档:

Hexo 高级玩家

如果你觉得前面的内容还不过瘾,那就来看这里吧!

编写自己的 Hexo 主题

在正式开始编写自己的主题之前,希望你多少具备点以下知识:

  • 前端知识:包含 HTML、CSS、JavaScript(这是一切的前提,不用多熟练,可以一边写一边练)
  • 一点基础的编程语法(至少知道什么是 forif
  • 会查看资料,包含但不限于官方文档、第三方文档
  • 出现问题会主动去寻找解决方法,推荐 Google
  • 模板引擎和预处理(这两个我是一边写一边学的)

:::tip 提醒
编写本文我不想重复造太多轮子,大多属于小坑提醒之类的。
:::

预备知识

模板引擎

Hexo 支持主流的模板引擎,如:EJSJadeSwing 等,本文我使用的是 EJS,可查看 文档

Hexo 的页面都是通过模板引擎渲染出来的页面,它可以实现一些代码的复用,若是采用一般的 HTML,则会造成很大的工作量,非常不方便,因此需要事先了解和学习一下。

CSS 预处理

与模板引擎一样,CSS 预处理能够更方便地写 CSS 样式,Hexo 中也支持大量的预处理,如:sassStylusLess 等,本文我是用的是 Stylus,可查看 文档

Hexo 官方文档

可到 Hexo 查看其文档,里面有很多用模板引擎用得到的变量以及辅助函数。

主题结构

Hexo 主题结构通常如下所示:

COPYtheme folder
├── languages    // 多语言文件夹
├── layout        // 页面文件
├── source        // 资源文件
└── _config.yml    // 主题配置文件

languages 文件夹放有一个或多个语言文件。

layout 文件夹下面用于存放页面文件,通常第一层有 Index 首页Archive 归档页Tag 标签页Category 分类页Post 文章页Page 页面详情页layout 布局,一般还会创建一个公共页面的文件夹,该文件夹用于放置一个页面的部分内容,用于复用。

source 文件夹用于放一些资源文件,例如:字体CSSJS图片 等,也会根据他们的文件类型进行再次分类,图片放到图片的文件夹,JS 放到 JS 的文件夹。

以上内容可以手动自建,也可以使用 generator-hexo-theme 来生成主题结构。

注意事项

我们在编写主题的时候,都是一边写一边就要看到效果,所以需要使用 hexo s 命令在本地运行,更改文件刷新页面就能看到效果,嫌弃麻烦的可使用 hexo-browsersync 插件,当修改主题文件保存后,浏览器将自动进行刷新。

在使用 hexo s 之前要先 hexo g修改主题配置文件时,不需要重新构建文件,修改根目录配置文件时,需要重新构建(hexo g

页面编写

编写推荐使用 VS Code 编辑器并安装 ejs、Stylus 插件。

先从 layout.ejs 文件开始,该文件是布局文件,其他页面都按照其来进行渲染,编写时遵循 HTML5 规范

COPY<!DOCTYPE html>
<html lang="<%= config.language %>">
<head>
    <%- partial('common/head') %>
</head>
<body>
    <%- partial('common/header') %>
    <div class="wrapper">
        <%- body %>
    </div>
    <%- partial('common/footer') %>
</body>
</html>

参考 官方文档 – 模板

  • config.language 表示使用根目录配置文件中 language 属性,假设配置文件中该属性填的是 zh-CN,则最终渲染成 <html lang="zh-CN">
  • partial() 用于引入公共布局,当引用后,每个页面都会存在你引用的这个布局,上面一共引用了三个文件 headheaderfooter,三个文件都在 common 文件夹下,这时候应该建立该文件夹,并在下面创建对应的三个 ejs 文件。假设 head.ejs 中的内容为 this is head,最终渲染成如下:(每个页面都会存在此内容)
COPY<head>
    this is head
</head>
  • <%- body %> 表示其他页面内容,例如:index.ejsarchive.ejs 等,假设 index.ejs 内容为 this is index,则最终渲染成如下:(因为是写在首页文件中,所以只有首页会存在该内容)
COPY<div class="wrapper">
    this is index
</div>

现在我们把其他文件也假设写出来。

文件 内容
index.ejs index
head.ejs head
header.ejs header
footer.ejs footer

最终渲染成的 index 为:

COPY<!DOCTYPE html>
<html lang="zh-CN">
<head>
    head
</head>
<body>
    header
    <div class="wrapper">
        index
    </div>
    footer
</body>
</html>

其他页面都是一样的用法,都是在生成在 <%- body %> 里面

数据使用

Hexo 中存在着三种变量数据:

  • 根目录配置文件:上面提到,该文件内的属性采用 config.XXX 来使用,更改此处属性要重新构建才能生效
  • 主题配置文件:和根目录配置文件使用方法一样,不过需要使用 theme.XXX 来调用,更改后无需重新构建
  • Hexo 预置:可查看 官方文档

配置文件数据

COPY# 根目录配置文件
title: STAUNCHKAI
subtitle: this is a subtitle

# 主题配置文件
avatar: /images/avatar.png
a
  b: https://staunchkai.com

分类页面 category.ejs 中内容如下:

COPY<div class="category-page">
    <h1><%= config.title %></h1>
    <p><%= config.subtitle %></p>
</div>
<div class="cateogry-page-other">
    <img src="<%= theme.avatar %>">
    <p><%= theme.a.b %></p>
</div>

最终渲染结果为:

COPY<!DOCTYPE html>
<html lang="zh-CN">
<head>
    head
</head>
<body>
    header
    <div class="wrapper">
        <div class="category-page">
            <h1>STAUNCHKAI</h1>
            <p>this is a subtitle</p>
        </div>
        <div class="cateogry-page-other">
            <img src="/images/avatar.png">
            <p>https://staunchkai.com</p>
        </div>
    </div>
    footer
</body>
</html>

Hexo 预置数据

post.ejs 文件内容如下:

COPY<div class="post">
    <h1><%= page.title %></h1>
    <p><%= page.tip %></p>
    <div class="post-content">
        <%- page.content %>
    </div>
</div>

一篇 md 文章内容如下:

COPY---
title: 这是一篇文章
tip: hexo 开发
---
主内容...

文章页面最终渲染成:

COPY<!DOCTYPE html>
<html lang="zh-CN">
<head>
    head
</head>
<body>
    header
    <div class="wrapper">
        <div class="post">
            <h1>这是一篇文章</h1>
            <p>hexo 开发</p>
            <div class="post-content">
                主内容...
            </div>
        </div>
    </div>
    footer
</body>
</html>

例子

举个复杂一丢丢的例子,主题配置文件如下:

COPYsocial:
  Github:
    url: https://github.com/staunchkai
    icon: icon-github
  Email:
    url: mailto:[email protected]
    icon: icon-email
  Rss:
    url: /atom.xml
    icon: icon-rss

要把 social 属性全部读取出来,如下:

COPY<div class="social">
    <% for (let i in theme.social) { %>
        <% let social = theme.socail[i]; %>
        <a href="<%- url_for(social.url) %>" class="<%= social.icon %>"><%= i %></a>
    <% } %>
</div>

最终结果:

COPY<div class="social">
    <a href="https://github.com/staunchkai" class="icon-github">Github</a>
    <a href="mailto:[email protected]" class="icon-email">Email</a>
    <a href="/atom.xml" class="icon-rss">Rss</a>
</div>

:::tip 提醒
按照上面的,导航栏菜单也是同样的方法。
:::

辅助函数

辅助函数参考 官方文档,官方文档最近几版更新的都比较详细,有具体的例子。在这里我挑几个来举例子。

条件函数

COPY<% if (is_home()) { %>    // 如果是首页
    <%- partial('common/header') %>    // 引入 header 文件
<% } %>

<% if (!is_archive()) { %>    // 如果不是归档页
    <%- partial('common/footer') %>    // 引入 footer 文件
<% } %>

日期

官方文档中有多个日期函数,但是我觉得使用下面这一个就足够了。

COPY官方文档
<%- date(date, [format]) %>

// 示例:
<%- date(Date.now()) %>
// 2013-01-01

<%- date(Date.now(), 'YYYY/M/D') %>
// Jan 1 2013

页面中的日期
<%- date(page.date, 'YYYY/M/D') %>    // 这样就能按照格式获取到页面中的日期

列表

官方文档中有 list_categorieslist_posts 等函数,都有具体的使用方法,在这里对于列表我写出我常用的方法。

文章列表:

对于文章通常有两种,一种是每页只显示 config.per_page 数量的文章,带有分页,另外一种是一个页面显示所有文章。

COPY// 带分页,使用 Hexo 预置变量 page.posts
<% page.posts.each(function(post) { %>    // 因为这里有个对象 post
    <h1><% post.title %></h1>    // 所以这里才可以用 post.title
    <%- partial('common/post-card') %>    // 这时引用一个文件
<% }); %>

post-card 文件内容为:
<div class="post-card">
    <%= post.title %>    // 这里是会报错的,无法通过
</div>

需要修改引用为:
<%- partial('common/post-card', {post: post}) %>    // 把 post 传过去才可使用

// 若没有传过去,只能使用 page.title,因为 Hexo 中没有预置 post 这个东东,具体可查看文档
COPY// 一个页面显示所有文章
<% site.posts.each(function(post) { %>
    <h1><% post.title %></h1>
    <%- partial('common/post-card', {post: post}) %>
<% }); %>

:::tip 提醒
上面两个,分别使用了官方文档中的两个变量 site.postspage.posts,请注意官方文档的重要性。
:::

分类列表:

COPY// 文章分类显示
<% page.categories.each(function(category) { %>        // 这里就没用 post.categories 了,除非是包含在上面的文章列表循环里面才可以用
    <a href="<%- url_for(category.path) %>"><%= category.name %></a>
<% }); %>

标签列表: 根据分类列表估计能把标签列表给弄出来了

其他页面

主题中原有的 category.ejstag.ejs 文件都是属于单个对象的页面,啥意思呢? 假设一篇文章 Front-matter 如下:

COPY---
categories:
    - 分类1
    - 分类2
tags:
    - tag1
    - tag2
---

category.ejs 页面只显示单个分类,当你点击分类1跳转过去的页面就是 category ,它不会显示出网站中所有的分类。

根据上面的可以看出,目前网站存在两个分类,想要全部显示出来,需要自行创建一个页面,这也就是在我们使用其他主题的时候,为啥什么 categoriestags 需要在根目录 source 文件夹下面创一个对应的文件夹,再创建一个 index.md 的原因所在,Hexo 里面没有预置这个东西。

tag.ejs 也同理。

还记得主题文件夹下面的 page.ejs 文件吗?他的作用就是用来创建其他文件的,只要把对应的内容写到这个文件里面就可以了。那我们除了分类、标签页面,还有友情链接、关于页面等等,难道全部写到一个文件里面吗?

显然这种做法是可行的,但是会导致文件内容复杂,将来不好维护,通常都会重新新建对应的一个页面文件,然后再到 page.ejs 里面引用即可。

下面做一个 关于 页面的例子:

  1. 首先在根目录资源文件夹创建一个名为 about 的文件夹,再到该文件夹下创建一个 index.md 文件,内容为:
COPY---
title: 关于
type: 'about'
---
这是一个关于页面内容
  1. 到主题文件夹中布局文件夹中创建一个 about.ejs 页面,内容为:
COPY<div class="about-page">
    <h1><%= page.title %></h1>
    <p><%- page.content %></p>
</div>
  1. page.ejs 中引入about.ejs
COPY<% if (is_page() && page.type === 'about') { %>    // 该文件是其他页面的集合,所以得判断啥情况引入啥文件
    <%- partial('about') %>
<% } %>

// 假设引入友情链接文件
<% if (is_page() && page.type === 'links') { %>    // is_page() 是啥请看官方文档 - 辅助函数
    <%- partial('links') %>
<% } %>
  1. 最终渲染结果
COPY<!DOCTYPE html>
<html lang="zh-CN">
<head>
    head
</head>
<body>
    header
    <div class="wrapper">
        <div class="about-page">
            <h1>关于</h1>
            <p>这是一个关于页面内容</p>
        </div>
    </div>
    footer
</body>
</html>

categories.ejstags.ejs 页面是不是就可以使用 site.categories.each...site.tags.each... 用同样的方式给弄出来了。

样式文件

如何在样式代码文件中引用主题文件的参数呢?假设主题配置文件中如下:

COPYcolor: '#c5cae9'

在 ejs 页面中完全可以使用 theme.color 来获取到该属性。

在 Stylus 文件中使用如下:

COPY$main-color = hexo-config('color')
// 或
mainColor = unquote(hexo-config("color"))

结语

目前就想到这些了,纯小白肯定是没法看懂的,本文大多属于小坑小提醒类型,最好具备文首所述的那些知识再来折腾比较好。

补充内容

本章将会放一些在上文中没讲到的东西。

YAML 语法简介

使用 Hexo 并不需要掌握过多的 YAML 语法知识,只需要简单的了解一下就可以。

Markdown 文件内使用 YAML

在 Hexo 中写文档,通常需要在头部写一些关于文章的信息,这些都是需要使用 YAML 语言来写的,例如

COPY---
title: 录制视频时显示按键
date: 2018-10-28 22:54:43
tags: [软件, 随便水水]

keywords: KeyCastOW 录屏技巧 按键显示
comments: true
---

:::tip 提醒

此部分一般叫做 Front-matter

:::

文章内部的 YAML 配置都是以 --- 开始和结束的,而且,结束之后通常还要再有一行的空行,用以区分 Markdown 语法。

_config.yml 中使用 YAML

这个就太常见了,Hexo 的配置文件和主题的配置文件都需要使用 YAML 语言来写。

基本语法

YAML 使用键值对的形式记录信息,标准格式是

COPYkey: value
键: 值

基本规则

  1. 大小写敏感
  2. 使用缩进表示层级关系
  3. 禁止使用 tab 缩进,只能使用空格键
  4. 缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级
  5. 使用 # 表示注释
  6. 字符串可以不用引号标注(但是建议你最好还是加上引号)

例如:

COPYhexo-tag-dplayer:
  cdn:
    - https://unpkg.com/dplayer/dist/DPlayer.min.js
    - https://unpkg.com/dplayer/dist/DPlayer.min.css
  default: 
    api: https://api.prprpr.me/dplayer3/
    loop: yes
    screenshot: yes

其中 hexo-tag-dplayer 是最高一级的,在模板里一般表示为 config.hexo-tag-dplayer;
观察缩进情况,可以发现 cdndefault 是同一级的,模板里一般表示为 config.hexo-tag-dplayer.cdnconfig.hexo-tag-dplayer.default
同理,default 下的三个选项又是一级,以此类推,只要记住缩进表示层级关系就可以了。

三种数据结构

scalar 纯量

scalar 不可再分割的量,这个你无需了解,因为了解了也没什么用。

map 散列表

键值对的集合,只要是出于同于缩进级别下的键值对,都可以称为一个 map (其实 map 也无需理解,因为这个太常见了,常见到你已经感觉不到它的存在了)

例如前面的 cdndefault 都在 hexo-tag-dplayer之下,并且处于同一缩进级别,就可以称为 map ;
map 有两种写法,最简单,也是最常用的就是前面的那种写法,如

COPYhexo-tag-dplayer:
  cdn: value
  default: value

等价于

:::v-pre

COPY{hexo-tag-dplayer: {cdn: value, default: value}}
# 或者是
hexo-tag-dplayer: {cdn: value, default: value}

:::

至于使用哪种写法,都是为了可读性。

例如在配置文件中,如果使用第二种写法,那所有配置都挤在一行,看都看不懂,而第一种写法缩进分明,一眼就能看出来层级关系;
但是在一些只需要很简单的配置的地方,比如 Hexo 文章开头的配置,第二种写法反而会可读性更高一些。

list 数组

划重点,这是本篇文章最有用的一节

list 的表示形式同样有两种

COPYkey:
  - value1
  - value2

或者

COPYkey: [value1, value2]

map 和 list 可以相互嵌套使用

使用建议

正如前面所说,使用哪种写法,都是为可读性服务的

我个人的建议是,当需要嵌套使用时,map 和 list 都尽量使用第一种写法,不需要嵌套使用时,尽量使用第二种写法,例如本篇文章的第一个例子

COPY---
title: 录制视频时显示按键
date: 2018-10-28 22:54:43
tags: [软件, 随便水水]

keywords: KeyCastOW 录屏技巧 按键显示
comments: true
---

数据文件

关于「数据文件」

::: theorem 数据文件

有时您可能需要在主题中使用某些资料,而这些资料并不在文章内,并且是需要重复使用的,那么您可以考虑使用 Hexo 3.0 新增的「数据文件」功能。此功能会载入 source/_data 内的 YAML 或 JSON 文件,如此一来您便能在网站中复用这些文件了。

Hexo 官方文档

如何使用?

大部分主题使用此特性都是为了平滑更新,使用方式可能如下:

  • 将主题目录下的 _config.yml 文件复制到博客根目录下的 /source/_data 中,并重命名为主题名称。例如我使用的是 melody 主题,那么就叫做 melody.yml 。如果 source 目录下没有 _data 文件夹请自行创建。
  • 之后升级主题便可直接使用 git pull or git fetch 命令完成主题更新。

某些主题也将数据文件特性用于存放一些设置数据。

总之,请注意主题的文档,每一个主题的使用方法都可能不一样

参考资料

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容