上篇说到我重新搭建起自己的博客,这篇讲讲目前写文章使用的工具以及主要使用到的工具。

等等,上篇才说到术和道的关系,咋现在又开始捣鼓起写博客的工具来了?

这,确实,这篇确实是关于工具的文章,但是主要不是捣鼓各种工具,而是记录下这次使用到的东西和用法,算是对这项工作的总结吧。

简单来说,目前我写文章会用到 emacs orgmode, ox-hugo, hugo, git, github pages 这几个东西,具体的流程如下:

  1. 使用 orgmode 来写文章

  2. 通过 ox-hugo 插件来将 org 文件转化为 markdown 文件

  3. 使用 hugomarkdown 文件生成静态网页

  4. 使用 git 将静态页面发布到 github pages

所用到的工具们

emacs + orgmode

作为一个在编辑器圣战中反复横跳的人,我用过 emacsvimsublimevscodeneovim。最近再使用了 neovim 作为工作开发的主力差不多一年,就在我以为它已经是我的最终归属的时候,我还是重新盼到回了初恋 emacs 的怀抱(哼,男人!)。

原因其实很简单,neovim 很优秀,但 lisp 太美了。neovimvscode 们像是一个干活很利索的工人,你告诉他你想做什么,他会告诉你能做还是不能做,如果能做就利索给你搞定,而 emacs 更像是个可以在你面前宽衣解带的姑娘,她不仅仅可以帮你帮事情做完,而且只要你有兴趣,就可以还不费力的窥见她做事的内部逻辑。

所以,目前我主力写文章的工具是 emacs + orgmodeorgmode 应该是所有 emacs 用户都会使用的mode了,因为用处很多,可以写文章,做笔记,做日程管理等等,但我目前主要使用的功能是写文章和记笔记。

ox-hugo

ox-hugoorgmode 的一个导出插件,主要功能就是在 orgmode 的导出选项中增加一个导出为 hugo 所要求的 markdown 格式的文件。可以解决使用 pandoc 转换的话要手动添加 hugo 要求的metadata的问题。

我目前配置 ox-hugo 的代码如下,我使用了 use-package 来进行 emacs 的插件管理:

1
2
3
(use-package ox-hugo
  :ensure t
  :after ox)

hugo

一款比较流行的static site generator,相比Jekyll,我其实不太在乎网页生成时间这种指标,只是使用Jekyll的话,需要本地安装 ruby 和一些依赖, hugo 则是直接编译好的一个二进制文件,相对来说要简洁很多。具体的用法可以参照 hugoquickstart

github pages

这个没有什么说的,比起自己搭建服务器,将博客这种简单的静态网页托管在 github 上确实非常方便。但是对于国内的用户,有可能 github 的访问可能不是非常稳定,所以我选择将内容放在 github 上,而域名是通过 cloudflare 的服务来管理。这样可以通过 cloudflare 来对流量做中转,虽然免费版的 cloudflare 说不上快,但是国内访问来说,还是比直接访问github.io来说要稳定一些。

文章的生成过程

下面大概解释下文章的格式转换和发布的流程。

构建基本目录结构

参照 hugo 的quickstart,建立一个自己的博客项目,其主要的目录结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
personal_blog $ ls -alh
total 8
drwxr-xr-x   3 qingyi  staff   96 Dec  3 20:52 archetypes/
-rw-r--r--   1 qingyi  staff  751 Dec  3 20:28 config.toml
drwxr-xr-x   3 qingyi  staff   96 Dec  3 12:45 content/
drwxr-xr-x   2 qingyi  staff   64 Dec  3 20:52 data/
drwxr-xr-x   2 qingyi  staff   64 Dec  3 20:52 layouts/
drwxr-xr-x   6 qingyi  staff  192 Dec  6 16:44 orgs/
drwxr-xr-x  11 qingyi  staff  352 Aug 31  1754 public/
drwxr-xr-x   3 qingyi  staff   96 Dec  3 20:54 resources/
drwxr-xr-x   3 qingyi  staff   96 Dec  6 16:43 static/
drwxr-xr-x   3 qingyi  staff   96 Dec  3 20:53 themes/

其中 config.toml 可以调整网站的各种样式于设置,可以参考 hugo 的文档修改。另外需要关注的是 orgs 目录,用来存储所有文章,我采用的是一篇文章对应一个 org 文件的方式, ox-hugo 还支持一个 org 文件中的一部分导出为一个 markdown 文件的方式,这里不多介绍了。另外一个目录是 public 目录,这个目录是 hugo 生成的静态文件的目录。这里我们通过 git submodule 命令,将 public 目录和我们 github pages 的仓库绑定:

1
$ git submodule add -b main [email protected]:[GITHUB_USER]/[GITHUB_USER].github.io.git public

这样,我们每次写完文章,利用 ox-hugo 转换为 markdown 的文章,再直接通过 hugo 命令,重新生成了 public 的目录,再通过 gitpublic 的仓库同步到Github就完成了文章的发布。

撰写文章

基本的目录结构构建好了之后,就可以开始写文章了,一般来说使用 hugo 来写文章会使用 hugo new posts/[POST_NAME] 的命令在 content/posts/ 的目录中生成文章的模版,模版中主要包括下面的metadata:

1
2
3
4
5
---
title: "My First Blog"
date: 2020-12-06T17:07:57+08:00
draft: true
---

hugo 在生成静态网页的时候会使用这些 metadata 来生成 categories 和 tags 等信息,所以我们的 org 文件中也要包括这些信息,借助于 ox-hugo 提供的功能,我们可以在 org 文件中直接标注这些信息,如下:

1
2
3
4
5
6
7
#+HUGO_BASE_DIR: ../
#+HUGO_SECTION: posts
#+HUGO_AUTO_SET_LASTMOD: t
#+HUGO_TAGS: emacs orgmode hugo github
#+HUGO_CATEGORIES: computer
#+HUGO_DRAFT: false
#+TITLE: 使用orgmode+hugo+github pages搭建博客

这里要注意 HUGO_BASE_DIRHUGO_SECTION 这两个属性,HUGO_BASE_DIR 是这个 hugo 项目的根目录,在我这个例子中为 personal_blog ,因为我的 org 文件存储在 personal_blog/orgs/ 目录中,所以设置为 ../HUGO_SECTION 这个属性指定了 ox-hugo 导出的文件在 content 目录中的子目录,这里默认的为 posts

这个 org 文件使用 orgmode 的导出命令,经过 ox-hugo 转换之后,会在 personal_blog/content/posts/ 的目录中生成对应的 markdown 文件,其中的 metadata 会转换为:

1
2
3
4
5
6
7
8
+++
title = "使用orgmode+hugo+github pages搭建博客"
author = ["Qing Yi"]
lastmod = 2020-12-06T17:13:46+08:00
tags = ["emacs", "orgmode", "hugo", "github"]
categories = ["computer"]
draft = false
+++

到这一步,我们就完成了文章的撰写和转换的过程。

文章的发布

到这一步就非常简单了,利用 hugo 命令会将 content 的内容生成为 html,并全部放入 public 目录,我们进入 public 目录,使用 git commitgit push 将最新的html推送到github就完成了文章的发布。

这一步可以通过编写shell来实现自动化,也可以使用 emacseasy-hugo 来实现自动化。目前我还有研究 easy-hugo 的插件,所以是写了个 deploy.fish 的脚本来做发布,内容如下:

 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
#! /usr/local/bin/fish
#我的shell是fish ,如果是bash, zsh可能不能运行/

echo "generating new site"

hugo

if test $status != 0
   echo "fail to generate new site"
   exit
end

cd public/

echo "commit all changes"

git add .

set msg echo rebuilding site at (date +'%Y-%m-%d %H:%M')

git commit -m "$msg"

echo "push to github"

git push origin main

相关连接