Rebuilding house

Photo by Randy Fath on Unsplash

之前趁著中國國慶假期,把之前用 Hexo 架的部落格遷移到 Hugo 了,自從 Hugo 出來後就一直很想換靜態部落格框架,Hexo 原先編譯速度太慢,我採用 Gitlab CI 自動集成,每次 Push 就會集成一次,修改一個檔案,可能要花上三分鐘以上才會部署上去,還有複雜的 npm 生態,安裝那些模組也很耗時,種種原因讓我想從 Hexo 換成 Hugo,而 Hugo 號稱世界上最快的靜態網站產生器,使用 Golang 編寫,性能優秀,產生網站十分迅速,一存檔就完成重載,跟 Hexo 比起來真的快多了。

安裝

Hugo 使用 Golang 撰寫,可編譯成二進制可執行檔,安裝起來也十分簡便,我使用的是 Arch Linux,pacman 一行指令直接搞定。

1
sudo pacman -S hugo

然後用 Hugo 建立一個新網站。

1
2
hugo new site blog
cd blog

佈景主題

這是遷移後比較大的問題,Hexo 擁有眾多漂亮主題,不少主題由中國網友開發,除了符合華人審美觀外,對中文支援也十分良好,目前好看的 Hugo 的中文主題還不多,目前我選用的是 Even,優點很多常用外掛都集成了,把網站語言設為 tw,翻譯檔手動翻譯成正體中文後基本就可以用了。

Even 範例網站

安裝主題跟 Hexo 類似,把 Repo Clone 到 themes 就行了。

1
2
cd themes
git clone https://github.com/olOwOlo/hugo-theme-even.git even 

config.toml 寫入 theme = "even",像 Even 這種完善的主題,可以複製 themes/even/exampleSiteconfig.toml 到網站根目錄,很多詳細設定像是留言板、Google Analysis 都寫在裡面了。

新增文章

Hugo 的文章放在 /content/posts 內,可以用指令來新增文章,而如果使用 Even 主題要將 posts 目錄名稱改成 post

hugo new posts/my-first-post.md

本機測試

跟 Hexo 一樣,可以先啟動一個本機伺服器來預覽效果,當文章內容或是佈景主題檔案變更會自動更新瀏覽器內容。

hugo server -D

產生靜態檔案

在網站根目錄開啟終端機,輸入 hugo 就會產生靜態網頁放置在 public 目錄。

佈署到 Github Pages

public 初始化 Git 倉庫,並加入遠端倉庫。

1
2
git init
git add remote upstream git@github.com:<username>/<username>.github.io.git

如果原本的 Git 倉庫已經有內容,但你不想要這些檔案,你可以在 push 的時候加上 -f 參數,只有第一次需要這樣做,之後就不用了。

1
2
3
git add . # 把 public 下所有檔案加入 git 倉庫
git commit -m "migrate to Hugo"
git push -f upstream master # 第一次需要加 -f,因為倉庫有內容

可以寫一個 deploy.sh 來自動佈署,省去繁雜的指令,腳本內容參考自這個部落格

 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
#!/bin/bash

echo -e "\033[0;32mDeploying updates to GitHub...\033[0m"

# build the project
hugo 

cd public

git add .

msg="rebuilding site `date`"

if [ $# -eq 1 ]
  then msg="$1"
fi

git commit -m "$msg"

# push source to github

git push upstream master

# come back to blog root

cd ..

增加執行權限。

1
$ chmod +x deploy.sh

當你完成一篇文章並準備發佈時,執行這個腳本就會產生靜態網頁檔並推送到 Github。

YAML Front Matter

Hugo 的 Front Matter 比較嚴格,不像 Hexo 一樣寬鬆,像日期格式在 Hugo 只能寫 YYYY-MM-DD,我平常在 Hexo 則寫 YYYY/MM/DD,這樣就無法識別了,必須修改每篇文章的 date 屬性,還好平常都懶得寫,只有少數幾篇,可以手動完成。

檔案名稱

我發現 Hugo 的 Front Matter 不支援 permalink,但可以透過 url 來設定固定網址,不過前綴也要寫入,所以我之前一篇文章的 permalinkuse-youtube-dl-to-download-videos,那我如果要瀏覽 /p/use-youtube-dl-to-download-videos 的話,那我 url 就要設定 /p/use-youtube-dl-to-download-videos,不是很靈活,而 Hugo 的網址命名規則預設是根據檔名產生,看了 Hugo 官方文件,可以在 config.toml 設定固定網址,並指定用檔案名稱,這樣就能保持先前在 Hexo 的網址結構,比較不影響 SEO。

如果你使用非 Even 主題,可能要將 post 改成 posts

1
2
[permalinks]
  post = "/p/:filename/"

閱讀更多標籤

我原本在 Hexo 的閱讀更多標籤習慣使用 <!-- more -->,而在 Hugo 要改寫成 <!--more-->,more 兩邊不能有空格,不然無法解析。

中國大陸使用者連線友好

之前因為 Gitlab 有免費 CI 服務就把部落格遷移到 Gitlab Pages,後來發現 Gitlab Pages 雖然服務周全,但延遲對於中國大陸有點高,經過我的調查,許多中國網友的部落格還是放在 Github Pages,而且也沒被牆,便決定遷回 Github Pages。

圖床的部份也從 Imgur 改成由 Showfom 大佬架設的 sm.ms,擁有多線 CDN,對各國使用者連線友好,除此之外上傳的圖片也要先經過壓縮避免載入太久,有些章首圖使用 Unsplash 的 CDN,通常要載入好一陣子,這次也一起下載回來改傳到 sm.ms 增進讀取速度。

更新:本文撰寫期間 sm.ms 已推出收費服務,免費版以撤除香港 CDN 節點改由 Cloudflare CDN 服務,部份地區速度可能變慢。

更換網址

因為我沒錢買網址、買主機,通常都是用活動送的免費網址,所以只能使用 Github 的子域名,這次從 Gitlab Pages 換到 Github 網址也跟著變了,SEO 必定也會受影響。

Disqus 遷移

首當其衝的應該就是 Disqus 的留言,還好 Disqus 對站長友好,官方提供更換網址的服務,進入 Disqus 管理界面,修改網站網址。

儲存設定後點下面的 Learn how 進入遷移工具,第二步修改網址。

Disqus 網址遷移工具

config.toml 填寫 Disqus 的 short name。

1
disqusShortname = "your-shortname"      # disqus_shortname

JS 轉址

要把原本的 Gitlab Pages 自動跳轉到現在的網頁,我寫了一段簡單的 JavaScript 程式碼放在 <head> 標籤中,這樣可以在載入完所有內容前就跳轉。

這段程式碼用了 URL API 來解析 URL,把網址變成一個物件,將 host 改成現在的網址,傳輸協議也自動換成 SSL,並把物件內容轉換成字串,丟到 window.location.href 來轉址。

1
2
3
4
5
6
7
<script>
    // redirect to new site
    var gitlab = new URL(window.location);
    gitlab.hostname = "junyussh.github.io";
    gitlab.protocol = "https";
    window.location.href = gitlab.toString();
</script>

Google Analytics

這個好像不需要設定網址,Google 是看你的追蹤程式碼去抓取資料的,主要問題是我不知道追蹤 ID 在哪看,網路也查不到,最後靠我自己摸索到了。

追蹤程式碼獲取位置

獲得追蹤 ID 後,通常佈景主題可以設定追蹤 ID,像 Even 就能直接在 config.toml 設定,但好像 Even 主題有 Bug,實際測試並沒有加上 Google Analytics 程式碼(詳見下文)。

1
googleAnalytics = "UA-XXXXXXXX-X"      # UA-XXXXXXXX-X

Search Console

Search Console 是用來分析文章曝光次數,網站熱門關鍵字的工具,可以得知哪個關鍵字曝光數最多。

因為換網址了,需要新增資源,如果你的網址是自己買的,有所有權,那請選左邊的 [網域],像我的是用 Github 提供的 github.io 子網域就要選右邊 [網址前置資源]。

選取資源類型

驗證方式我採用 Google Analytics,因為我本來就有用 Google Analytics 分析服務,可以參考 Goolge 官方的教學文章,把這段程式碼放到 <head> 裡。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->

注意:程式碼片段必須放在 <head> 中,否則無法驗證。

我發現 Even 主題貌似有 Bug,在 Layout 裡面沒有寫 Google Analytics 的程式碼,於是我手動修改了佈景主題程式碼。

themes/even/layouts/partials/head.html 添加了這段程式碼。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!-- Analytics -->
{{- if .Site.GoogleAnalytics -}}
<!--  {{ template "_internal/google_analytics_async.html" . }}-->
<script>
  (function (i, s, o, g, r, a, m) {
  i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
    (i[r].q = i[r].q || []).push(arguments)
  }, i[r].l = 1 * new Date(); a = s.createElement(o),
    m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
  })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');

  ga('create', '{{ .Site.GoogleAnalytics }}', 'auto');
  ga('send', 'pageview');
</script>
{{- end -}}

config.toml 加入你的追蹤 ID 即可用上 Google Analytics。

1
googleAnalytics = "UA-XXXXXXXX-X"

Reference