说是第一篇文章,其实是转到 Hugo 以后的第一篇文章。

至于转到 hugo 的原因,见下面的两篇文章。

总的来说,就是 npm 对 package 的依赖管理松散,再加上 hexo 社区对一些常用 plugins 惰于升级维护,导致 dependencies 经常冲突。升级不是,不升级也不是。最后干脆什么都用不了。

以前是重新安装一个 hexo 环境,还有几率能解决依赖的问题(部分 plugins 会降级安装)。但既然已经不是第一次遇到这种情况,问题的根源解决不了,没准儿以后还会遇到,干脆下定决心弃坑 hexo。

hugo 早就听说大名,golang 也是我喜欢的。基本上没调研其它 blog service,直接开始研究起 hugo 来。

1. 安装 hugo

我用 MacBook Pro,装了 HomeBrew,安装 hugo 相对简单。

brew install hugo

2. 建立站点

hugo new site my-blog

完成以后,my-blog 目录下会有以下子目录。

  • archetypes: 下面有一个 default.md 的模板,是新建文章的时候,会用到的模板。
  • config.toml: TOML 格式的配置文件。
  • content: 放文章源文件,.md 文件的地方。
  • themes: 主题目录。具体用哪个主题,参照 config.toml 里面的配置。
  • static: 静态文件的目录。这里的文件,会被 hugo 原样拷贝到 public 目录中。
  • public: 编译后的目录。这里的文件通过你在 config.toml 中设置的 baseURL 直接访问。发布的博客,编译后,把这个目录的内容直接发布到外网即可。

3. 主题

3.1. 安装主题

cd <my-blog>
git init
git clone https://github.com/rujews/maupassant-hugo themes/maupassant

修改 config.toml 中下面的配置。

theme = "maupassant"

3.2. 配置主题

config.toml

baseURL = "http://i.am.simonkuang.com/"
languageCode = "cmn-Hans"
title = "旷氏淇元"
theme = "maupassant"

preserveTaxonomyNames = false  # false 的话,分类名称会自动小写。默认是 false
disablePathToLower = false  # true 的话,防止 hugo 自动将 url 转小写。默认是 false

#googleAnalytics = "UA-45245769-1"

[author]
  name = "Simon"

[params]
  author = "Simon"
  subtitle = "旷淇元的个人博客"
  keywords = ""
  description = ""
  customJS = ['baidu.js', 'mermaid.js']

3.3. 友情链接

config.toml

[[params.links]]
  title = "agentzh 的 Nginx 教程"
  name = "agentzh 的 Nginx 教程"
  url = "http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html"
[[params.links]]
  title = "gitflow-cheatsheet"
  name = "gitflow-cheatsheet"
  url = "http://danielkummer.github.io/git-flow-cheatsheet/index.zh_CN.html"
[[params.links]]
  title = "Laruence"
  name = "Laruence"
  url = "http://www.laruence.com/"

3.4. 自定义菜单

config.toml

[menu]
  [[menu.main]]
    identifier = "books"
    name = "新书"
    url = "/books/"
    weight = 2
  [[menu.main]]
    identifier = "archives"
    name = "归档"
    url = "/archives/"
    weight = 3
  [[menu.main]]
    identifier = "about"
    name = "关于"
    url = "/about/"
    weight = 4

3.5. 文章归档操作

hugo new content/archives/index.md

content/archives/index.md

---
title: "归档"
date: 2000-06-10T11:41:46+08:00
description: 小旷的个人博客。记录生活学习和工作的二三事。
type: archives
---

3.6. 其它静态文件

有些不需要我们转化的静态文件,比如 robots.txt、我们上传的附件等,这些不需要 Hugo 进行处理,可以直接放在 static 目录下,编译阶段,Hugo 会原封不动的拷贝到 public 目录下,方便一起部署。

4. Mermaid 插件

Mermaid 还是必要的。必须保留,不然没法儿画图。

cd <my-blog>
mkdir -p static/js
mkdir -p layouts/shortcodes

static/js/mermaid.js

;;(function() {
  var _mermaid_init = function() {
    mermaid.initialize({
      startOnLoad: true,
      theme: 'forest',
      // themeCSS: '.node rect { fill: red; }',
      logLevel: 3,
      flowchart: { curve: 'linear' },
      gantt: { axisFormat: '%m/%d/%Y' },
      sequence: { actorMargin: 50 },
      // sequenceDiagram: { actorMargin: 300 } // deprecated
    });
  };

  var hm = document.createElement("script");
  hm.src = "//unpkg.com/mermaid@8.0.0/dist/mermaid.min.js";
  hm.onload = _mermaid_init;
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(hm, s);

  (function() {
    var codelist = document.querySelectorAll('code.language-mermaid');
    if (codelist && 'length' in codelist && codelist.length > 0) {
      for (var i = 0; i < codelist.length; i++) {
        var div = document.createElement('div');
        div.className = 'mermaid';
        div.setAttribute('align', 'center');
        div.innerHTML = codelist[i].innerHTML.replace(/&amp;/g, '&');
        codelist[i].replaceWith(div);
      }
    }
  })();
})();

layouts/shortcodes/mermaid.html

<div class="mermaid">
  {{ .Inner }}
</div>
<script src="//unpkg.com/mermaid@8.0.0/dist/mermaid.min.js" defer></script>

config.toml

[params]
  customJS = ['mermaid.js']   # static/js/mermaid.js 会被添加到所有页的 footer 位置

如此这般,以后画图,可以用下面的方式操作。

```mermaid
sequenceDiagram
  participant Publisher
  participant Broker
  participant Subscriber
  Publisher->>Publisher: Store(Msg)
  Publisher->>Broker: PUBLISH(QoS2, Msg)
  Broker->>Broker: Store(Msg)
  Broker->>Publisher: PUBREC
  Publisher->>Broker: PUBREL
  Broker->>Subscriber: PUBLISH(QoS2, Msg)
  Broker->>Publisher: PUBCOMP
  Publisher->>Publisher: Delete(Msg)
  Subscriber->>Subscriber: Store(Msg)
  Subscriber->>Broker: PUBREC
  Broker->>Subscriber: PUBREL
  Subscriber->>Subscriber: Notify(Msg)
  Subscriber->>Broker: PUBCOMP
  Broker->>Broker: Delete(Msg)
  Subscriber->>Subscriber: Delete(Msg)
```

得到的效果如下。

sequenceDiagram
  participant Publisher
  participant Broker
  participant Subscriber
  Publisher->>Publisher: Store(Msg)
  Publisher->>Broker: PUBLISH(QoS2, Msg)
  Broker->>Broker: Store(Msg)
  Broker->>Publisher: PUBREC
  Publisher->>Broker: PUBREL
  Broker->>Subscriber: PUBLISH(QoS2, Msg)
  Broker->>Publisher: PUBCOMP
  Publisher->>Publisher: Delete(Msg)
  Subscriber->>Subscriber: Store(Msg)
  Subscriber->>Broker: PUBREC
  Broker->>Subscriber: PUBREL
  Subscriber->>Subscriber: Notify(Msg)
  Subscriber->>Broker: PUBCOMP
  Broker->>Broker: Delete(Msg)
  Subscriber->>Subscriber: Delete(Msg)

当然,按照 hugo shortcodes 的语法,写成下面这样也没问题。就是太啰嗦,一点不 markdown。

{{< mermaid >}}
sequenceDiagram
  participant Publisher
  participant Broker
  participant Subscriber
  Publisher->>Publisher: Store(Msg)
  Publisher->>Broker: PUBLISH(QoS2, Msg)
  Broker->>Broker: Store(Msg)
  Broker->>Publisher: PUBREC
  Publisher->>Broker: PUBREL
  Broker->>Subscriber: PUBLISH(QoS2, Msg)
  Broker->>Publisher: PUBCOMP
  Publisher->>Publisher: Delete(Msg)
  Subscriber->>Subscriber: Store(Msg)
  Subscriber->>Broker: PUBREC
  Broker->>Subscriber: PUBREL
  Subscriber->>Subscriber: Notify(Msg)
  Subscriber->>Broker: PUBCOMP
  Broker->>Broker: Delete(Msg)
  Subscriber->>Subscriber: Delete(Msg)
{{< /mermaid >}}

参考如下。

  1. 从Hexo迁移到Hugo-送漂亮的Hugo Theme主题
  2. 把博客生成工具从 Hexo 迁移到 Hugo — 配置与设置
  3. Create Your Own Shortcodes
  4. Mermaid Migration Example from Theme Learn