Compare commits

..
Author SHA1 Message Date
JimmyandGitHub 768e7de697 refactor: update RSS template to the latest one given by Hugo, and change page output logic (#1257)
* refactor: rename `home.rss.xml` to `rss.xml`

* refactor: update RSS template to the latest one given by Hugo.

Output pages with the same logic as in normal site by using `helper/pages`
2026-01-30 15:27:32 +01:00
JimmyandGitHub 00069b2c45 feat: add muted attribute and refine autoplay condition for video shortcode (#1256) 2026-01-30 15:09:33 +01:00
JimmyandGitHub 31022581d8 refactor: image logic in page (#1255)
* fix: add SVG check in helper/image before accessing .Width and .Height

* refactor: drop image resizing logic in render-image, and use helper/image to process image

* fix: render-image $permalink not correct
2026-01-30 15:07:14 +01:00
Jimmy Cai ff2e308445 fix: correct pluralization of 'minute' in English reading time. 2026-01-27 14:04:16 +01:00
JimmyandGitHub 017fbf982d chore: update Traditional Chinese localization files (#1251)
closes https://github.com/CaiJimmy/hugo-theme-stack/issues/1222
2026-01-27 12:49:44 +01:00
JimmyandGitHub bc54cecf0a refactor: centralize page filtering logic, and allow sort by lastmod (#1250)
* refactor: migrate page visibility control from `Params.hidden` to the new `build.list` parameter.

* refactor: centralize page filtering logic into a new `helper/pages.html` partial

* feat: introduce `SortBy` parameter to enable sorting pages by last modified date

* refactor: extract page sorting logic into a new `pages-sort.html` partial
2026-01-27 12:34:15 +01:00
JimmyandGitHub deceb17144 refactor: migrate page visibility control from Params.hidden to the new build.list parameter. (#1249)
* refactor: migrate page visibility control from `Params.hidden` to the new `build.list` parameter.

* Rename rss.xml to home.rss.xml
2026-01-27 12:00:40 +01:00
Jimmy Cai dc0d105e7c fix: correct global site context access for the home page link in the sidebar 2026-01-27 00:05:05 +01:00
JimmyandGitHub 33b7de9457 refactor: use .Site.Home.RelPermalink for home page links in the sidebar (#1248)
refactor: use `.Site.Home.RelPermalink` for home page links in the sidebar.
2026-01-26 23:59:40 +01:00
JimmyandGitHub 7d4bfa9fc0 refactor: simplify sidebar avatar configuration and don't resize (#1247) 2026-01-26 23:58:18 +01:00
19 changed files with 158 additions and 197 deletions
+2 -1
View File
@@ -5,7 +5,8 @@ date: {{ .Date }}
image:
math:
license:
hidden: false
comments: true
draft: true
build:
list: always # Change to "never" to hide the page from the list
---
+6 -5
View File
@@ -2,6 +2,11 @@ mainSections = ["post"]
featuredImageField = "image"
rssFullContent = true
# Accepted values: "default", "lastmod"
# default = see https://gohugo.io/quick-reference/glossary/#default-sort-order
# lastmod = sort by last modified date, in descending order
SortBy = "default"
[footer]
since = 2026
customText = ""
@@ -12,11 +17,7 @@ rssFullContent = true
[sidebar]
compact = false
[sidebar.avatar]
enabled = false
local = true
src = "img/avatar.png"
avatar = ""
[article]
headingAnchor = false
+1 -4
View File
@@ -8,10 +8,7 @@ favicon = "img/avatar.png"
[sidebar]
emoji = "✏️"
subtitle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
[sidebar.avatar]
enabled = true
local = true
src = "img/avatar.png"
avatar = "img/avatar.png"
[article]
[article.license]
+1 -1
View File
@@ -20,7 +20,7 @@ darkMode = "Dark Mode"
[article.readingTime]
one = "{{ .Count }} minute read"
other = "{{ .Count }} minute read"
other = "{{ .Count }} minutes read"
[notFound]
title = "Not Found"
+12 -21
View File
@@ -2,46 +2,37 @@ toggleMenu = "切換選單"
darkMode = "深色模式"
[list]
section = "Section"
[list.page]
one = "第 {{ .Count }} 頁"
other = "第 {{ .Count }} 頁"
[list.subsection]
one = "Subsection"
other = "Subsections"
page = "{{ .Count }} 篇文章"
section = "章節"
subsection = "子章節"
[article]
back = "返回"
tableOfContents = "目錄"
relatedContent = "相關內容"
lastUpdatedOn = "上次改過於"
[article.readingTime]
one = "需要 {{ .Count }} 分鐘閱讀"
other = "需要 {{ .Count }} 分鐘閱讀"
readingTime = "閱讀時間 {{ .Count }} 分鐘"
[notFound]
title = "Not Found"
subtitle = "頁面不存在"
title = "找不到頁面"
subtitle = "頁面不存在"
[widget]
[widget.archives]
title = "Archives"
title = "歸檔"
more = "更多"
[widget.tagCloud]
title = "Tags"
title = "標籤"
[widget.categoriesCloud]
title = "Categories"
title = "分類"
[search]
title = "搜尋"
placeholder = "Type 關鍵字..."
resultTitle = "#PAGES_COUNT pages (#TIME_SECONDS seconds)"
placeholder = "輸入關鍵字..."
resultTitle = "找到 #PAGES_COUNT 個結果 (用時 #TIME_SECONDS )"
[footer]
builtWith = "Built with {{ .Generator }}"
builtWith = "使用 {{ .Generator }} 建立"
designedBy = "主題 {{ .Theme }} 由 {{ .DesignedBy }} 設計"
+4 -13
View File
@@ -2,25 +2,16 @@ toggleMenu = "切換選單"
darkMode = "夜晚模式"
[list]
section = "段落"
[list.page]
one = "第 {{ .Count }} 頁"
other = "第 {{ .Count }} 頁"
[list.subsection]
one = "小節"
other = "小節"
section = "段落"
page = "第 {{ .Count }} 頁"
subsection = "小節"
[article]
back = "返回"
tableOfContents = "目錄"
relatedContent = "相關文章"
lastUpdatedOn = "最後更新"
[article.readingTime]
one = "閱讀時間: {{ .Count }} 分鐘"
other = "閱讀時間: {{ .Count }} 分鐘"
readingTime = "閱讀時間: {{ .Count }} 分鐘"
[notFound]
title = "404 錯誤"
+5 -27
View File
@@ -1,34 +1,12 @@
{{- $image := .Page.Resources.GetMatch (printf "%s" (.Destination | safeURL)) -}}
{{- $Permalink := .Destination | relURL | safeURL -}}
{{- $image := partial "helper/image" (dict "Resources" .Page.Resources "Image" .Destination) -}}
{{- $alt := .PlainText | safeHTML -}}
{{- $Width := 0 -}}
{{- $Height := 0 -}}
{{- $Srcset := "" -}}
{{/* SVG and external images won't work with gallery layout, because their width and height attributes are unknown */}}
{{- $galleryImage := false -}}
{{- $galleryImage := and $image.Height $image.Width -}}
{{- if $image -}}
{{- $notSVG := ne (path.Ext .Destination) ".svg" -}}
{{- $Permalink = $image.RelPermalink -}}
{{- if $notSVG -}}
{{- $Width = $image.Width -}}
{{- $Height = $image.Height -}}
{{- $galleryImage = true -}}
{{- if .Page.Site.Params.imageProcessing.content.enabled -}}
{{- $small := $image.Resize `480x` -}}
{{- $big := $image.Resize `1024x` -}}
{{- $Srcset = printf `%s 480w, %s 1024w` $small.RelPermalink $big.RelPermalink -}}
{{- end -}}
{{- end -}}
{{- end -}}
<img src="{{ $Permalink }}"
{{ with $Width }}width="{{ . }}"{{ end }}
{{ with $Height }}height="{{ . }}"{{ end }}
{{ with $Srcset }}srcset="{{ . }}"{{ end }}
<img src="{{ $image.Permalink }}"
{{ with $image.Width }}width="{{ . }}"{{ end }}
{{ with $image.Height }}height="{{ . }}"{{ end }}
loading="lazy"
{{ with $alt }}
alt="{{ . }}"
@@ -1,4 +1,4 @@
{{ $related := (where (.Site.RegularPages.Related .) "Params.hidden" "!=" true) | first 5 }}
{{ $related := (.Site.RegularPages.Related .) | first 5 }}
{{ with $related }}
<aside class="related-content--wrapper">
<h2 class="section-title">{{ T "article.relatedContent" }}</h2>
+28 -29
View File
@@ -9,45 +9,44 @@
/// Height: Image height
/// Width: Image width
{{ $result := dict
"Local" false
"Resource" nil
"Permalink" (.Image | absURL)
"Width" nil
"Height" nil
}}
{{ $result := "" }}
{{ if not .Image }}
{{ $result = "" }}
{{ else }}
{{ if .Image }}
{{ $url := urls.Parse .Image }}
{{ $resource := "" }}
{{ if not (in (slice "https" "http") $url.Scheme) }}
{{ $resource := .Resources.Get (printf "%s" (.Image | safeURL)) }}
{{ if $resource }}
{{ $resource = .Resources.Get (printf "%s" (.Image | safeURL)) }}
{{ else }}
{{ with try (resources.GetRemote $url) }}
{{ with .Err }}
{{ errorf "%s" . }}
{{ else with .Value }}
{{ $resource = . }}
{{ else }}
{{ errorf "Unable to get remote resource %q" $url }}
{{ end }}
{{ end }}
{{ end }}
{{ if $resource }}
{{- $isSVG := eq $resource.MediaType.SubType "svg" -}}
{{- if $isSVG -}}
{{ $result = dict
"Local" true
"Resource" $resource
"Permalink" $resource.RelPermalink
"Height" nil
"Width" nil
}}
{{- else -}}
{{- $result = dict
"Local" true
"Resource" $resource
"Permalink" $resource.RelPermalink
"Height" $resource.Height
"Width" $resource.Width
}}
{{ end }}
{{ else }}
{{ with try (resources.GetRemote $url) }}
{{ with .Err }}
{{ errorf "%s" . }}
{{ else with .Value }}
{{ $result = dict
"Local" false
"Resource" .
"Permalink" .RelPermalink
"Height" .Height
"Width" .Width
}}
{{ else }}
{{ errorf "Unable to get remote resource %q" $url }}
{{ end }}
{{ end }}
{{- end -}}
{{ end }}
{{ end }}
+7
View File
@@ -0,0 +1,7 @@
{{- $pages := .Pages -}}
{{- if eq .Context.Site.Params.SortBy "lastmod" -}}
{{- $pages = $pages.ByLastmod.Reverse -}}
{{- end -}}
{{- return $pages -}}
+16
View File
@@ -0,0 +1,16 @@
{{- $pages := .Pages -}}
{{- if .IsHome -}}
{{- $pages = where .Site.RegularPages "Type" "in" .Site.Params.mainSections -}}
{{- else if or (eq .Kind "section") (eq .Kind "taxonomy") (eq .Kind "term") -}}
{{- $subsections := .Sections -}}
{{- $pages = .Pages | complement $subsections -}}
{{- if eq (len $pages) 0 -}}
{{- $pages = $subsections -}}
{{- end -}}
{{- end -}}
{{- $pages := partial "helper/pages-sort.html" (dict "Pages" $pages "Context" .) -}}
{{- return $pages -}}
+5 -25
View File
@@ -1,28 +1,8 @@
{{- $pages := slice -}}
{{- $hasPages := false -}}
{{- $result := slice -}}
{{- if .IsHome -}}
{{ $pages = where .Site.RegularPages "Section" "in" .Site.Params.mainSections }}
{{ $pages = where $pages "Params.hidden" "!=" true }}
{{- $hasPages = true -}}
{{- else if eq .Kind "term" -}}
{{ $pages = where .Pages "Params.hidden" "!=" true }}
{{- $hasPages = true -}}
{{- else if or (eq .Kind "section") (eq .Kind "taxonomy") -}}
{{ $subsections := .Sections }}
{{ $pages = .Pages | complement $subsections }}
{{ $pages = where $pages "Params.hidden" "!=" true }}
{{- if eq (len $pages) 0 -}}
{{/* See complete logic in list.html */}}
{{- $pages = $subsections -}}
{{- end -}}
{{- $hasPages = true -}}
{{- if or .IsHome (eq .Kind "section") (eq .Kind "taxonomy") (eq .Kind "term") -}}
{{- $pages := partial "helper/pages.html" . -}}
{{- $result = .Paginate $pages -}}
{{- end -}}
{{- if $hasPages -}}
{{ $pages = .Paginate $pages }}
{{- end -}}
{{ return $pages }}
{{- return $result -}}
+9 -17
View File
@@ -7,32 +7,24 @@
<header>
{{ with .Site.Params.sidebar.avatar }}
{{ if .enabled }}
{{- $avatar := partial "helper/image" (dict "Image" . "Resources" resources) -}}
<figure class="site-avatar">
<a href="{{ .Site.BaseURL | relLangURL }}">
{{ if not .local }}
<img src="{{ .src }}" width="300" height="300" class="site-logo" loading="lazy" alt="Avatar">
{{ else }}
{{ $avatar := resources.Get (.src) }}
{{ if $avatar }}
{{ $avatarResized := $avatar.Resize "300x" }}
<img src="{{ $avatarResized.RelPermalink }}" width="{{ $avatarResized.Width }}"
height="{{ $avatarResized.Height }}" class="site-logo" loading="lazy" alt="Avatar">
{{ else }}
{{ errorf "Failed loading avatar from %q" . }}
{{ end }}
{{ end }}
<a href="{{ $.Site.Home.RelPermalink }}">
<img src="{{ $avatar.Permalink }}"
width="{{ $avatar.Width }}"
height="{{ $avatar.Height }}"
class="site-logo"
loading="lazy"
alt="Avatar">
</a>
{{ with $.Site.Params.sidebar.emoji }}
<span class="emoji">{{ . }}</span>
{{ end }}
</figure>
{{ end }}
{{ end }}
<div class="site-meta">
<h1 class="site-name"><a href="{{ .Site.BaseURL | relLangURL }}">{{ .Site.Title }}</a></h1>
<h1 class="site-name"><a href="{{ .Site.Home.RelPermalink }}">{{ .Site.Title }}</a></h1>
<h2 class="site-description">{{ .Site.Params.sidebar.subtitle }}</h2>
</div>
</header>
+2 -3
View File
@@ -9,9 +9,8 @@
</div>
<h2 class="widget-title section-title">{{ T "widget.archives.title" }}</h2>
{{ $pages := where $context.Site.RegularPages "Type" "in" $context.Site.Params.mainSections }}
{{ $filtered := where $pages "Params.hidden" "!=" true }}
{{ $archives := $filtered.GroupByDate "2006" }}
{{ $pages := partial "helper/pages.html" $context.Site.Home }}
{{ $archives := $pages.GroupByDate "2006" }}
<div class="widget-archive--list">
{{ range $index, $item := first (add $limit 1) ($archives) }}
+5 -4
View File
@@ -1,10 +1,11 @@
{{- $src := .Get "src" | default (.Get 0) -}}
<div class="video-wrapper">
<video
controls
src="{{- $src -}}"
{{ with .Get "poster" }}poster="{{- . -}}"{{ end }}
{{ with .Get "autoplay" }}autoplay{{ end }}
controls
src="{{- $src -}}"
{{ with .Get "poster" }}poster="{{- . -}}"{{ end }}
{{ if eq (.Get "autoplay") "true" }}autoplay{{ end }}
{{ if eq (.Get "muted") "true" }}muted{{ end }}
>
<p>
Your browser doesn't support HTML5 video. Here is a
+2 -3
View File
@@ -15,10 +15,9 @@
{{ end }}
</header>
{{ $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections }}
{{ $filtered := where $pages "Params.hidden" "!=" true }}
{{ $pages := partial "helper/pages.html" .Site.Home }}
{{ range $filtered.GroupByDate "2006" }}
{{ range $pages.GroupByDate "2006" }}
{{ $id := lower (replace .Key " " "-") }}
<div class="archives-group" id="{{ $id }}">
<h2 class="archives-date section-title"><a href="{{ $.RelPermalink }}#{{ $id }}">{{ .Key }}</a></h2>
+2 -6
View File
@@ -29,14 +29,10 @@
</div>
</header>
{{- $pages := partial "helper/pages.html" . -}}
{{- $subsections := .Sections -}}
{{- $pages := .Pages | complement $subsections -}}
{{- $pages = where $pages "Params.hidden" "!=" true -}}
{{- if eq (len $pages) 0 -}}
{{/* If there are no normal pages, display subsections in list style, with pagination */}}
{{/* This happens with taxonomies like categories or tags */}}
{{- $pages = $subsections -}}
{{- if and (eq (len $pages) (len $subsections)) (eq $pages $subsections) -}}
{{- $subsections = slice -}}
{{- end -}}
+2 -4
View File
@@ -1,9 +1,7 @@
{{- $pages := where .Site.RegularPages "Type" "in" .Site.Params.mainSections -}}
{{- $filtered := where $pages "Params.hidden" "!=" true -}}
{{- $pages := partial "helper/pages.html" .Site.Home -}}
{{- $result := slice -}}
{{- range $filtered -}}
{{- range $pages -}}
{{- $data := dict "title" .Title "date" .Date "permalink" .RelPermalink "content" (.Plain) -}}
{{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) -}}
+48 -33
View File
@@ -1,48 +1,63 @@
{{- $pctx := . -}}
{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
{{- $pages := slice -}}
{{- if or $.IsHome $.IsSection -}}
{{- $pages = $pctx.RegularPages -}}
{{- else -}}
{{- $pages = $pctx.Pages -}}
{{- $authorEmail := "" -}}
{{- with site.Params.author -}}
{{- if reflect.IsMap . -}}
{{- with .email -}}
{{- $authorEmail = . -}}
{{- end -}}
{{- end -}}
{{- end }}
{{- $authorName := "" -}}
{{- with site.Params.author -}}
{{- if reflect.IsMap . -}}
{{- with .name -}}
{{- $authorName = . -}}
{{- end -}}
{{- else -}}
{{- $authorName = . -}}
{{- end -}}
{{- end -}}
{{- $pages := where $pages "Params.hidden" "!=" true -}}
{{- $pages := partial "helper/pages.html" . -}}
{{- $limit := .Site.Config.Services.RSS.Limit -}}
{{- if ge $limit 1 -}}
{{- $pages = $pages | first $limit -}}
{{- $pages = $pages | first $limit -}}
{{- end -}}
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML -}}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{ . }} on {{ end }}{{ .Site.Title }}{{ end }}</title>
<link>{{ .Permalink }}</link>
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
<language>{{.}}</language>{{end}}{{ with .Site.Params.Author.email }}
<managingEditor>{{.}}{{ with $.Site.Params.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Params.Author.email }}
<webMaster>{{.}}{{ with $.Site.Params.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
<copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{ . }} {{ end }}{{ end }}on {{ .Site.Title }}</description>
<generator>Hugo -- gohugo.io</generator>
<language>{{ site.Language.LanguageCode }}</language>{{ with $authorEmail }}
<managingEditor>{{.}}{{ with $authorName }} ({{ . }}){{ end }}</managingEditor>{{ end }}{{ with $authorEmail }}
<webMaster>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</webMaster>{{ end }}{{ with .Site.Copyright }}
<copyright>{{ . }}</copyright>{{ end }}{{ if not .Date.IsZero }}
<lastBuildDate>{{ (index $pages.ByLastmod.Reverse 0).Lastmod.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
{{- with .OutputFormats.Get "RSS" -}}
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
{{- end -}}
{{ range $pages }}
{{- $content := safeHTML (.Summary | html) -}}
{{- if .Site.Params.rssFullContent -}}
{{- $content = safeHTML (.Content | html) -}}
{{- end -}}
{{- range $pages -}}
<item>
<title>{{ .Title }}</title>
<link>{{ .Permalink }}</link>
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
{{ with .Site.Params.Author.email }}<author>{{.}}{{ with $.Site.Params.Author.name }} ({{.}}){{end}}</author>{{end}}
<guid>{{ .Permalink }}</guid>
<description>
{{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) -}}
{{- if $image -}}
{{ "<" | html }}img src="{{ $image.permalink | absURL }}" alt="Featured image of post {{ .Title }}" {{ "/>" | html}}
{{- end -}}{{ $content }}</description>
<title>{{ .Title }}</title>
<link>{{ .Permalink }}</link>
<pubDate>{{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
{{- with $authorEmail }}<author>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</author>{{ end }}
<guid>{{ .Permalink }}</guid>
<description>
{{- $content := .Summary -}}
{{- if .Site.Params.RSSFullContent -}}
{{- $content = .Content -}}
{{- end -}}
{{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) -}}
{{- if $image -}}
{{- $imgTag := printf "<img src=\"%s\" alt=\"Featured image of post %s\" />" ($image.permalink | absURL) .Title -}}
{{- $content = printf "%s%s" $imgTag $content -}}
{{- end -}}
{{- $content | transform.XMLEscape | safeHTML -}}
</description>
</item>
{{ end }}
{{- end -}}
</channel>
</rss>