由於原先使用 Jekyll 的 voyager theme 所建立的靜態 Blog 在功能上已有些不足,且 Jekyll 的過慢的編譯速度也讓人有些頭大,因此有了轉換網網頁產生器的想法。原本是想使用 Hexo 來當作新的產生器,但在找產生器的過程發現了 Hugo 這個靜態網頁產生器中的新起之秀,研究後發現相當符合個人需求,因此決定使用 Hugo 來作為新的靜態網頁產生器。

Hugo

Hugo 是一套由 Go 語言開發的 Static Site Generator (靜態網頁產生器,以下簡稱 SSG),可讓使用者透過 Markdown 語法撰寫內容後建立靜態網頁並發佈,讓使用者能專注在內容上。除了 Hugo 外,也有其他如 JekyllHexo 等知名 SSG。和其他 SSG 比起來,Hugo 包含許多不同的特點,如

快速

速度應該是 Hugo 最大的特色了,由於 Hugo 是由 Go 語言撰寫並編譯為二進位執行檔,與由 Ruby 所撰寫的 Jekyll 和由 Javascript 所撰寫的 Hexo 相比起來,Hugo 的網頁生成速度快上許多。以我的狀況,雖然原先 Jekyll 的網頁內容不多且使用的 theme 與 hugo 不同,但每次修改後 jekyll 重新建立網頁內容都須花上 1~2 秒,相比起來 Hugo 只需使用到 10~20 ms,網頁生成速度快了將近 100 倍。

安裝方便

對初學者來說,使用 Jekyll 與 Hexo 先安裝 gem 或 npm 等在不同平台的套件管理器,也間接增加了進入難度(即使對一般工程師來說沒問題)。Hugo 只需下載不同平台的 Binary 檔案如同一般程式進行安裝後即可使用與更新,不需像 gem 與 npm 需再而外安裝許多套件。

內容與 Theme 管理

和 Jekyll 相比,Hugo 將 theme 與 內容資料夾分開,使用者可更簡單的進行 theme 的切換相當方便,不過目前與 Jekyll 和 Hexo 相比,Hugo 可選擇的 theme 還不是很多,這點就需要更多人投入了。

Hugo 建立靜態網頁範例

Install Hugo

因 Hugo 已將 Go 語言程式轉換為二進位執行檔,因此只需要直接安裝 Hugo 即可,在 macOS 上可使用 Homebrew 套件管理安裝

brew install hugo

或直接到 Hugo 的 GitHub Release 上下載最新版本程式

Generate new site

要產生一個新的 web site 內容,可直接執行

hugo new site ssg-site

執行後會建立一個名為 ssg-site 的資料夾,包含以下內容

.
├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes

其中

  • archetypes: 放置生成文件的基礎樣板資料夾(可先暫時不管)。
  • config.toml: 控制 hugo 產生網頁內容的設定檔,預設使用 toml 格式。(也支援 yaml 與 json 格式)
  • content: 放置 Markdown 文章與網頁內容的資料夾。
  • data: 儲存一些 configuration 檔案的地ㄌㄌ方,協助建構靜態網頁(也先不管)。
  • layouts: 儲存產生的網頁 layout 樣板(之後範例使用其他的 theme,先不管)。
  • static: 放置靜態內容,如圖片,CSS 以及 *.js 等內容。
  • themes: 從外部引入的 theme 檔案。

目前只要知道 config.toml, content, staticthemes 這幾個部分即可。

Import Hugo themes

Hugo 並沒有預設的 theme,所以在建立好內容資料夾後,需自行建立 theme 或使用其他 theme,在這我們已 Mainroad theme 做範例。

# 將 mainroid theme 加入 themes/ 中
git clone https://github.com/Vimux/Mainroad.git themes/mainroad

除了使用 git 指令外,直接從 Github 上下載最新原始檔案壓縮檔,解壓縮後放到 themes 資料夾中。此外對 git 熟悉的是使用者也可用 git submodulegit subtree 等方式管理外部引入的 theme repo。

Configuration

Hugo 在生成 SSG 時會使用到 config.toml 檔案的設定內容。我們可以將之前 Mainroad theme 中的 config.toml 修改後加以使用

# 將 mainroid 的 config.toml 覆蓋原先的預設值
cp themes/mainroad/exampleSite/config.toml .

之後編輯 config.toml 內容,將其修改為自己想要的內容。更詳細的 configuration 設定可參考 Hugo 官方文件

新增 Blog 文章

我們可以手動新增 Markdown 文件

hugo new post/hello-world.md

之後會在 ./content/post/hello-world.md 的位置新增一個 Markdown 文件,其中預設內容會根據 archetype/default.md 這個樣板檔案內容加以建立。

預覽內容

先將 ./content/post/hello-world.md 內容修改為

---
title: "Hello World"
date: 2018-07-06T16:00:21+08:00
categories:
  - "Blog"
tags:
  - "Hugo"
draft: true
---

# Hello World.

Post example

之後執行以下指令

hugo server --buildDrafts

若在 Markdown 的 Front Matter,加入 draft: true,代表該篇文章為草稿不會被 Hugo 轉換為網頁。因此可在指令後加入 --buildDrafts 來轉換草稿文件。

執行成功後會在 localhost:1313 建立一個暫時的網頁,可接載在瀏覽器網址列輸入預覽結果。

hugo-preview Hugo Mainroad theme 結果預覽

1313 為 Hugo 的預設 Port,可以使用 --port xxx 來指定使用其他 Port

生成靜態內容

Hugo 要生成靜態網頁內容只執行 hugo 指令即可

hugo

執行後生成的網頁內容會自動加入 public 資料夾中。

public 為預設資料夾,若要修改可在 config 檔案中設定 publishDir 參數指定輸出位置。

從 Jekyll 轉移到 Hugo

如果要從其他的 SSG 轉換到 Hugo,官方也提供了一些轉換方式。以從 Jekyll 轉換到 Hugo 為例,只要執行

hugo import jekyll [jekyll_root_path] [target_path]

就會將 Jekyll 轉換為 Hugo 格式資料夾。但這方式也不是沒問題,原先在的 Jekyll 的 theme 無法直接在 Hugo 使用,且有部分 Front Matter 無法正確轉換,因此建議還是手動轉移較好。而因爲個人轉移時選用的 theme 為 Mainroad,在過程中也遇到了一些問題,在此提出來以供參考。

Markdown Front Matter

由於 Hugo 與 Jekyll 所使用的 Front Matter 設定不同,有些部分需要每個檔案逐一修改內容,如 categoriestags 的內容,之前使用的 voyager theme 在執行時會成格式不對,需修改將其改為 List 結構,如在 Jekyll 中,

categories: posts

是可行的,但換到 Hugo 的 Mainroad theme 時,需使用 List 結構才行,如

categories: ["posts"]

才可正常產生靜態網頁,否則會出現錯誤。

Math equation support

在加入數學式的支援花了一些時間去解決,主要分為兩個問題 - Markdown 轉換成 HTML 以及 Mainroad theme 的 CSS conflict 問題。

Markdown parser support

在加入數學式時,我們習慣直接使用 Latex 語法在 Markdown 中,這樣可以更容易寫出方便的數學式。而 Hugo 預設的 Markdown parser Blackfriday(使用 Go 語言實作的 Markdown parser) 會進行某些預先處理,造成 MathJax 無法正確顯示內容以及斷行的問題。因此需要將原先的 Blackfriday parser 更換成 Mmark,即在 Markdown 文件中使用 Latex 數學式語法。方法為將檔案副檔名命名為 *.mmark,或是在 Markdown Front Matter 中加入 markup: "mmark" 來指定使用 Mmark 處理 Markdown 文件。更詳細的內容可參考官網說明。

Katex support

雖然 Mainroad theme 雖然有支援 MathJax,但該 theme 的 CSS style 中有部分和 Katex 的 CSS 設定衝突,造成當把 Mainroad 中的 MathJax 部分的樣板原始碼換成支援 Katex 後,在顯示 Matrix 時會造成跑版。詳情狀況可參考個人發在 GitHub 上的 Issue #1445。在 Katex 小組了解問題並經過 Mainroad 作者修改樣板後即解決了該問題。

Syntax highlighting

要在 Hugo 中讓程式碼有高亮效果,可在 config 檔案中加入以下設定

# use Chroma for syntax highlight
pygmentsCodeFences = true # 啟動 Code Fence 區域的高亮效果
pygmentsCodefencesGuessSyntax = true # 對沒有指定程式類型的 Code Fence 自行推導語言類型
pygmentsStyle = "fruity" # 指定使用的高亮風格,如 vim 或 fruity 等(預設為 "monokai")

若想換成其他風格可參考這裡的格式,將 pgmentsStyle 的設定修改為該風格 Hugo 就會用該風格顯示 Markdown 中 Code Fence 區段的內容。其他設定可參考 Hugo 官網關於 Syntax Hightlighting 的章節。

pygment 為原先 Hugo 所使用的 Syntax Hightlighting 工具, 在 Hugo 0.28 版後改為 Chroma 為預設內容,但設定檔仍維持原先的格式。

首頁大綱內容

Mainroad 的 Markdown 文件顯示在列表中的大綱內容,會是最前面段落開始一直延續到預設長度為止,這在排版上會很難看,因此可以手動在 Markdown 文件中加入 <!--more--> 標籤隔開大綱與主題內容,如下範例


...{大綱內容}...

<!--more-->

...{文章內容}...

這樣在首頁的列表中就只會顯示大綱內容的部分。

Disqus Support

Hugo 本身所產生的內容為靜態網頁,若要有像留言板之類的動態內容就必須藉助外部服務。Hugo 本身支援 Disqus 這個知名的 Blog 留言服務樣板,只要建立帳號取得 shortname,在 config 檔案中設定完成即可。若使用的 theme 有支援應該能正確顯示

disqusShortname = "yourdiscussshortname"

Google Analysis support

和 Disqus 相同,Hugo 也有內部支援 Google Analysis 來統計你網站的流量與人潮。只要去 Google Analysis 申請一組 Tracking Id 並在 config 中加入設定。如 使用的 theme 有支援該功能則會自動設定

googleAnalytics = "yourtrackingid"

Reference