×

Kuncen WB1, Wirobrajan 10010, DIY

(+68) 120034509

info@yourdomain.com

技術筆記|Hugo Widget 開發 - 系列文章列表

閱讀成本 3 分鐘 #技術筆記

不知道會不會有人跟我遇到一樣的撞牆,或者有一樣的想法?不過我想要記錄下來,這樣有相同問題的人可以一起找到可能的解方喔!

如果你跟我一樣是電腦玩物的讀者,那對於文章下面會列出系列相關文章的排版方式應該都不陌生。

自從轉換到 Hugo 之後,很多東西都是可以自己開發的,只要符合 Hugo 內部的語言設定。網路上有許多開放論壇的問題與資源,這也引起了我業餘自主學習的 Coding 魂,剛好目前看到的資源中,並沒有在文章底下加入系列文章的相關內容,就決定來自己研究一下。

系列文章示意圖
系列文章示意圖

文章最下面可自動叫出系列文章

我需要的設定如下:

  1. 可以自己抓取相同系列的文章;
  2. 依照發佈時間順序去排序。

一如往常,中間經歷過幾次撞牆期。

撞牆期

一開始我覺得,找得了很棒的解決方法,看到網路上有人分享相關的程式碼如下:

一行程式碼但不支援變數

<ul>
   {{ range .Site.Taxonomies.categories.golang }}
   <li><a href="{{ .URL }}">{{ .Name }}</a></li>
   {{ end }}
</ul>

利用這一段程式碼,我們可以針對某個 categories 跑出相關的文章,進一步的產生列表。

看到這個程式碼的時候,我覺得如獲至寶,這根本就是我想要的,而且只要簡單的幾行就可以完成,只要我能夠想到怎麼更換 golang 這裡成為變數即可。

但後來發現,在這一段程式碼之中,Hugo 並不支援直接把 .Site.Taxonomies.categories.XXXX 裡面的 XXXX 使用變數替代。等於,除非我新增無數的頁面,然後手動的插入,不然這個方法並不是我想要的。

partial 傳送函數

換個角度想,如果我能夠創建 partial 的 HTML 檔案,把檔案名稱使用變數帶入,或許也是一種做法。

所以找了相關的內容,看是否能夠把 partial 的 HTML 檔名透過變數帶入,但發現這樣的做法非常不實際。在搜尋的過程中,看到相關資料好像可以把變數帶到 partial 去的 HTML 之中。

反覆的測試之後,不知道為什麼都無法成功的把變數帶過去,所以這個方法還是宣告失敗。

category 比對後只顯示相同的

走到這邊,我忽然想到,不如透過 Taxonomy 的概念,直接把所有文章列出,依照 category 分組排序,這部分其實在官方的文件檔案中就已經有支援。

再透過比對,僅顯示跟當篇文章有相同的 category 的文章列表。

這一個方法感覺上蠻好的,但會有一個長期的侷限性,就是雖然我目前都是只把 category 設定唯一,但這個職也是被鎖死了,未來如果真的想要活化的話,變成千一髮動全身。

考量長久下來,可能會想要活化 category 的使用,暫時不採用這樣的方式。

最終解法:創造新的 Taxonomy ,使其成為唯一值

接下來參考到一篇文章寫道可以使用 series 的概念,等於創造了一個系列文章的感覺。

忽然腦中冒出了:「賓果」。

既然我想要保留 category 的擴充性,那就創建一個 series 去做真的屬於「系列文章」該做的事情吧。

config.toml

在設定的同時,分別把需要使用 Taxonomy 定義好,此前我並沒有定義 category 跟 tags,透過這次一起完成。

[taxonomies]
    category = "categories"
    series = "series"
    tags = "tags"

Single.html

在文章頁面中,文章內容的最下面,將確認有設定 series 的文章,做兩件事情。

.Scratch.Set 設定 session series_name 值為此系列的名稱。

{{if .Params.series}}
  {{ $name := index .Params.series 0 }}
  {{ $.Scratch.Set "series_name" $name }}
{{end}}

然後,比對到相同的 series_name 則把相關的文章依 PublishDate 列出。

{{if .Params.series}}
下面列出系列文章,方便有興趣的朋友點擊閱讀:
<section id="menu">
    <ul>
        {{ range $key, $taxonomy := .Site.Taxonomies.categories }}
        {{ if eq $key ($.Scratch.Get "series_name") }}
            {{ range $taxonomy.Pages.ByPublishDate }}
                <li hugo-nav="{{ .RelPermalink}}"><a href="{{ .Permalink}}"> {{ .LinkTitle }} </a> </li>
            {{ end }}
        {{ end }}
        {{ end }}
    </ul>
</section>
{{ end }}

文章 .md 檔案的表頭(front)

在上面都設定完之後,接下來的控制選項就回到了每一篇文的表頭之中。

因為 Hugo 可以容許我們在表頭自訂許多項目,加上我們已經定義了 series 為 Taxonomy 的一環,所以我可以在表頭直接新增此項目。

series = [系列名稱]

雖然設定的是陣列的格式,但其實在上面的程式碼之中,只會抓取陣列的第一個欄位的職,所以多填無益。這背後其實有把 series, categories, tags 三個做區別的概念。

之後只要我有設定 series 在表頭之中,都會自動幫我啟動系列文章列表,並把相關的文章依發表時間依序列出。

感謝電腦玩物啟發,讓我想要使用這的版面,以前都覺得需要透過 javascript 經過一連串複雜的判斷等等,或者只能夠手動增減。這次透過 Hugo 程序架構,順利完成。

我把這一系列文章整理在下面,有興趣的朋友可以點擊閱讀:

如果您喜歡這篇文章,歡迎訂閱電子報,也請不吝留言鼓勵、討論或分享到自己的社群中,文章採用創用 CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款授權,分享、引用請依授權規定,並附上原文連結(按右鍵複製連結):技術筆記|Hugo Widget 開發 - 系列文章列表