目錄

在網站首頁新增依發佈或更新日期排序的按鈕

前言

有時候在瀏覽網站時,就想看最近有更新的文章。但因為本站使用的是 Hugo ,而 Hugo 是靜態網頁生成器,首頁中的文章訊息在網站生成的一刻都寫死了,無法做到動態切換。這時,我們就可以利用生成一個類似於首頁的頁面,透過按鈕切換不同頁面,達到類似動態網頁的效果,完成文章排序功能。

新增切換按鈕

我們可以在首頁的任何地方加入切換按鈕。在這裡,我們採用類似如下的切換開關,並加入動畫,而後於文章出現的頂端加入按鈕。

👈像是這種的

本站目前使用的主題是 LoveIt 主題,我們可以在網站跟目錄的 /layouts/ 路徑中找到首頁 html 檔案 index.html ,並在文章起始處的 {{- /* Posts */ -}} 上方加入以下程式碼。

 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
{{- /* 排序切換開關 */ -}}
<div class="sort-toggle">
    <span>{{ i18n "publishDate_updateDate" }}</span>
    <label class="switch">
        <input type="checkbox" id="sort-toggle">
        <span class="slider round"></span>
    </label>
</div>

<style>
    /* 開關樣式 */
    .switch {
        position: relative;
        display: inline-block;
        width: 50px;
        height: 24px;
        margin: 0 10px;
    }

    .switch input {
        opacity: 0;
        width: 0;
        height: 0;
    }

    .slider {
        position: absolute;
        cursor: pointer;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: #ccc;
        transition: .4s;
        border-radius: 24px;
    }

    .slider:before {
        position: absolute;
        content: "";
        height: 18px;
        width: 18px;
        left: 4px;
        bottom: 3px;
        background-color: white;
        transition: .4s;
        border-radius: 50%;
    }

    input:checked + .slider {
        background-color: #2196F3;
    }

    /* 平滑滑動動畫 */
    input:checked + .slider:before {
        transform: translateX(26px);
    }

    input:not(:checked) + .slider:before {
        transform: translateX(0);
    }
</style>

<script>
    document.addEventListener("DOMContentLoaded", function () {
        var lang = (document.documentElement.lang || 'en').toLowerCase();
        var siteLang = '{{ (index .Site.Languages 0).Lang }}'.toLowerCase();

        var lastmodUrl = lang === siteLang ? "/lastmod" : `/${lang}/lastmod`;
        var homeUrl = lang === siteLang ? "/" : `/${lang}/`;

        var toggleSwitch = document.getElementById("sort-toggle");

        // 根據當前網址設定開關狀態
        if (window.location.pathname.includes("/lastmod")) {
            toggleSwitch.checked = true;
        }

        // 監聽開關變化並切換頁面
        toggleSwitch.addEventListener("change", function () {
            window.location.href = this.checked ? lastmodUrl : homeUrl;
        });
    });
</script>

接下來就可以在網站首頁看到切換按鈕啦,如果要使用其他種類的按鈕也可以在這裡更換。

修改國際化語言檔案

如果有點開首頁,我們會發現按鈕前方的字似乎不正常,這是因為尚未在語言檔案中加入翻譯鍵。我們可以依據以下步驟新增翻譯鍵。

到網站根目錄的 /i18n/ 目錄下找到網站對應的語言檔案,並新增 publishDate_updateDate 鍵值。以下使用繁體中文 (zh-TW) 和英文 (en) 示範。

zh-TW.toml

1
2
[publishDate_updateDate]
other = "發佈日期 / 更新日期"

en.toml

1
2
[publishDate_updateDate]
other = "Publish Date / Update Date"

這樣按鈕前的文字就正常了。

新增 index.lastmod.html 模板

按下按鈕後,我們會發現沒有反應。這是因為我們尚未新增不同排序的網頁。因此,我們可以複製一份 /layouts/index.html 首頁的檔案,並在網站根目錄的 /layouts/posts/ 路徑貼上,同時修改名稱為 index.lastmod.html 。而後,在 {{- /* Posts */ -}} 中新增 {{- $pages = $pages.ByLastmod.Reverse -}} 以實現依照更新時間排序。具體修改如下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
{{- /* Posts */ -}}
{{- if ne $posts.enable false | and .Site.RegularPages -}}
    {{- /* Paginate */ -}}
    {{- $pages := where .Site.RegularPages "Type" "posts" -}}

    {{- $pages = $pages.ByLastmod.Reverse -}} {{- /* 新增這行 */ -}}

    {{- if .Site.Params.page.hiddenFromHomePage -}}
        {{- $pages = where $pages "Params.hiddenfromhomepage" false -}}
    {{- else -}}
        {{- $pages = where $pages "Params.hiddenfromhomepage" "!=" true -}}
    {{- end -}}
    {{- with $posts.paginate | default .Site.Params.paginate -}}
        {{- $pages = $.Paginate $pages . -}}
    {{- else -}}
        {{- $pages = .Paginate $pages -}}
    {{- end -}}
    {{- range $pages.Pages -}}
        {{- .Render "summary" -}}
    {{- end -}}
    {{- partial "paginator.html" . -}}
{{- end -}}

新增文章並修改成首頁

最後的最後,我們只要產生一份文章,並指定生成剛剛寫的模板,就完成了。

我們在網站根目錄的 /content/ 目錄中新增 homepage.lastmod 資料夾,並新增 _index.語言代碼.md 檔案,同時填入以下內容。

1
2
3
4
5
6
7
8
---
title: "homepage.lastmod"
url: "lastmod"
date: 2025-03-28T21:00:11+08:00  # 這是當時的日期,可以修改成自己的
draft: false
type: "posts"
layout: "index.lastmod"
---

如果是多語言網站,記得新增對應的 _index.語言代碼.md 檔案,填入的內容都是相同的。例如本站新增的檔案如下。

1
2
3
4
5
/content/
│── homepage.lastmod/
│   ├── _index.zh-tw.md
│   └── _index.en.md

至此,我們就擁有了依據發佈日期或更新日期顯示不同文章排序的功能了。

結語

我從以前就很想實現這個功能,但是研究了許久都無法繞過靜態網頁生成的架構。偶然間想到能夠生成一個不同排序的網頁並使用超連結往返,最後在網路上搜尋資料時發現可行,終於完成修改。

運行環境

  • Hugo 0.144.2
  • LoveIt 主題(2025 年 2 月 21 日 Github 上的版本)

參考資料