Compare commits

..
Author SHA1 Message Date
JimmyandGitHub f5adf4a273 fix: do not display the date of term pages (#1296) 2026-03-05 18:25:04 +01:00
JimmyandGitHub 07fa7615eb refactor: simplify article-list/tile partial context passing (#1295)
refactor: simplify `article-list/tile` partial context passing and internal usage.
2026-03-05 18:15:05 +01:00
JimmyandGitHub 628bb9a501 feat: use images.AutoOrient in helper/image (#1294)
* feat: use images.AutoOrient in `helper/image`

closes https://github.com/CaiJimmy/hugo-theme-stack/issues/1292

* fix: check if IsImageResourceProcessable before using filter

* remove local field

* feat: add configurable image auto-orientation via a new `autoOrient` parameter in site configuration
2026-03-05 17:58:40 +01:00
JimmyandGitHub 11aa9e349a refactor: rename article-footer to article-meta (#1293)
* refactor: rename `article-footer` to `article-meta`, and remove unnecesary structures

* fix: Update default article license URL to point to Creative Commons.
2026-03-05 17:10:35 +01:00
22 changed files with 90 additions and 121 deletions
+9 -22
View File
@@ -71,12 +71,11 @@
gap: 8px; gap: 8px;
} }
.article-footer, .article-meta {
.article-translations,
.article-header-tags {
display: flex; display: flex;
color: var(--card-text-color-tertiary); flex-direction: column;
gap: var(--spacing-md); gap: var(--spacing-lg);
font-size: 1.4rem;
svg { svg {
vertical-align: middle; vertical-align: middle;
@@ -86,30 +85,22 @@
flex-shrink: 0; flex-shrink: 0;
} }
&,
time, time,
a { a,
span {
font-size: 1.4rem; font-size: 1.4rem;
color: var(--card-text-color-tertiary); color: var(--card-text-color-tertiary);
} }
& > div { & > .inline-meta {
display: inline-flex; display: inline-flex;
flex-wrap: wrap;
align-items: center; align-items: center;
gap: var(--spacing-md); gap: var(--spacing-md);
} }
} }
.article-time {
flex-wrap: wrap;
}
.article-translations,
.article-header-tags {
& > div {
flex-wrap: wrap;
}
}
.article-category, .article-category,
.article-tags { .article-tags {
display: flex; display: flex;
@@ -173,10 +164,6 @@
} }
} }
.article-footer {
font-size: 1.4rem;
}
.article-preview { .article-preview {
font-size: 1.4rem; font-size: 1.4rem;
color: var(--card-text-color-tertiary); color: var(--card-text-color-tertiary);
+1 -35
View File
@@ -45,41 +45,7 @@
.article-footer { .article-footer {
margin: var(--card-padding); margin: var(--card-padding);
margin-top: 0; gap: var(--spacing-2xl);
section:not(:first-child) {
margin-top: var(--card-padding);
}
section {
color: var(--card-text-color-tertiary);
text-transform: uppercase;
display: flex;
align-items: center;
font-size: 1.4rem;
gap: 15px;
svg {
width: 20px;
height: 20px;
stroke-width: 1.33;
}
}
.article-tags {
text-transform: unset;
}
.article-copyright,
.article-lastmod {
a {
color: var(--body-text-color);
}
a.link {
box-shadow: unset;
}
}
} }
} }
} }
+2
View File
@@ -76,6 +76,8 @@ SortBy = "default"
default = "auto" default = "auto"
[imageProcessing] [imageProcessing]
autoOrient = false
[imageProcessing.content] [imageProcessing.content]
widths = [800, 1600, 2400] widths = [800, 1600, 2400]
enabled = true enabled = true
+1 -1
View File
@@ -13,7 +13,7 @@ favicon = "img/avatar.png"
[article] [article]
[article.license] [article.license]
enabled = true enabled = true
default = "Licensed under CC BY-NC-SA 4.0" default = "Licensed under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)"
[widgets] [widgets]
homepage = [ homepage = [
+1 -1
View File
@@ -1,4 +1,4 @@
{{- $image := partial "helper/image" (dict "Resources" .Page.Resources "Image" .Destination) -}} {{- $image := partial "helper/image" (dict "Resources" .Page.Resources "Image" .Destination "Context" .Page) -}}
{{- $alt := .PlainText | safeHTML -}} {{- $alt := .PlainText | safeHTML -}}
{{- $title := .Title | markdownify -}} {{- $title := .Title | markdownify -}}
+10 -6
View File
@@ -11,19 +11,23 @@
{{- $description = $description | default (T "list.page" (len .Pages)) -}} {{- $description = $description | default (T "list.page" (len .Pages)) -}}
{{- end -}} {{- end -}}
{{- if or $description (not .Date.IsZero) -}} {{- if or $description (not .Date.IsZero) -}}
<footer class="article-footer"> {{/*
{{- if not .Date.IsZero -}} If it's a term, the date is extracted from the first page of the collection, which is not very useful.
In that case, we prefer to display the description (if set), or the number of pages within the collection.
*/}}
<footer class="article-meta">
{{- if or $IsTerm .Date.IsZero -}}
<span class="article-description">{{- $description -}}</span>
{{- else if not .Date.IsZero -}}
<time datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}"> <time datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}">
{{- .Date | time.Format .Site.Params.dateFormat.published -}} {{- .Date | time.Format .Site.Params.dateFormat.published -}}
</time> </time>
{{- else if $description -}} {{- end }}
<span class="article-description">{{- $description -}}</span>
{{ end }}
</footer> </footer>
{{- end -}} {{- end -}}
</div> </div>
{{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) -}} {{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources "Context" .) -}}
{{ if $image }} {{ if $image }}
<div class="article-image"> <div class="article-image">
{{ partial "helper/thumbnail-image" (dict {{ partial "helper/thumbnail-image" (dict
+1 -1
View File
@@ -1,4 +1,4 @@
{{ $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) }} {{ $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources "Context" .) }}
<article class="{{ if $image }}has-image{{ end }}"> <article class="{{ if $image }}has-image{{ end }}">
{{ partial "article/components/header" (dict "Page" . "IsList" true) }} {{ partial "article/components/header" (dict "Page" . "IsList" true) }}
</article> </article>
+5 -5
View File
@@ -1,16 +1,16 @@
{{ $image := partial "helper/image" (dict "Image" .context.Params.image "Resources" .context.Resources) }} {{ $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources "Context" .) }}
<article class="{{ if $image }}has-image{{ end }}"> <article class="{{ if $image }}has-image{{ end }}">
<a href="{{ .context.RelPermalink }}"> <a href="{{ .RelPermalink }}">
{{ if $image }} {{ if $image }}
<div class="article-image"> <div class="article-image">
{{ partial "helper/thumbnail-image" (dict {{ partial "helper/thumbnail-image" (dict
"Resource" $image.Resource "Resource" $image.Resource
"Width" 250 "Width" 250
"Height" 150 "Height" 150
"Resize" .context.Site.Params.ImageProcessing.Thumbnail.Enabled "Resize" .Site.Params.ImageProcessing.Thumbnail.Enabled
"Attributes" (dict "Attributes" (dict
"src" $image.Permalink "src" $image.Permalink
"alt" (printf "Featured image of post %s" .context.Title) "alt" (printf "Featured image of post %s" .Title)
"loading" "lazy" "loading" "lazy"
"width" $image.Width "width" $image.Width
"height" $image.Height "height" $image.Height
@@ -30,7 +30,7 @@
{{- end -}} {{- end -}}
> >
<h2 class="article-title"> <h2 class="article-title">
{{- .context.Title -}} {{- .Title -}}
</h2> </h2>
</div> </div>
</a> </a>
@@ -30,48 +30,47 @@
{{ $showReadingTime := $Page.Params.readingTime | default ($Page.Site.Params.article.readingTime) }} {{ $showReadingTime := $Page.Params.readingTime | default ($Page.Site.Params.article.readingTime) }}
{{ $showDate := not $Page.Date.IsZero }} {{ $showDate := not $Page.Date.IsZero }}
{{ $showFooter := or $showDate $showReadingTime }} {{ $showTime := or $showDate $showReadingTime }}
{{ if $showFooter }} {{ $showTranslations := $Page.IsTranslated }}
<footer class="article-footer"> {{ $showTags := and $Page.Site.Params.Article.List.ShowTags ($Page.GetTerms "tags") $IsList }}
{{ if $showDate }}
<div> {{ if or $showTime $showTranslations $showTags }}
{{ partial "helper/icon" "date" }} <footer class="article-meta">
<time class="article-time--published" datetime='{{ $Page.Date.Format "2006-01-02T15:04:05Z07:00" }}'> {{ if $showTime }}
{{- $Page.Date | time.Format $Page.Site.Params.dateFormat.published -}} <div class="inline-meta">
</time> {{ if $showDate }}
{{ partial "helper/icon" "date" }}
<time class="article-time--published" datetime='{{ $Page.Date.Format "2006-01-02T15:04:05Z07:00" }}'>
{{- $Page.Date | time.Format $Page.Site.Params.dateFormat.published -}}
</time>
{{ end }}
{{ if $showReadingTime }}
{{ partial "helper/icon" "clock" }}
<time class="article-time--reading">
{{ T "article.readingTime" $Page.ReadingTime }}
</time>
{{ end }}
</div> </div>
{{ end }} {{ end }}
{{ if $showReadingTime }} {{ if $showTranslations }}
<div> <div class="inline-meta">
{{ partial "helper/icon" "clock" }} {{ partial "helper/icon" "language" }}
<time class="article-time--reading">
{{ T "article.readingTime" $Page.ReadingTime }}
</time>
</div>
{{ end }}
</footer>
{{ end }}
{{ if $Page.IsTranslated }}
<footer class="article-translations">
{{ partial "helper/icon" "language" }}
<div>
{{ range $Page.Translations }} {{ range $Page.Translations }}
<a href="{{ .RelPermalink }}" class="link">{{ .Language.LanguageName }}</a> <a href="{{ .RelPermalink }}" class="link">{{ .Language.LanguageName }}</a>
{{ end }} {{ end }}
</div> </div>
</footer> {{ end }}
{{ end }}
{{ if and $Page.Site.Params.Article.List.ShowTags ($Page.GetTerms "tags") $IsList }} {{ if $showTags }}
<footer class="article-header-tags"> <div class="article-tags inline-meta">
{{ partial "helper/icon" "tag" }} {{ partial "helper/icon" "tag" }}
<div>
{{ range ($Page.GetTerms "tags") }} {{ range ($Page.GetTerms "tags") }}
<a href="{{ .RelPermalink }}" class="link">{{ .LinkTitle }}</a> <a href="{{ .RelPermalink }}" class="link">{{ .LinkTitle }}</a>
{{ end }} {{ end }}
</div> </div>
</footer> {{ end }}
</footer>
{{ end }} {{ end }}
</div> </div>
@@ -1,15 +1,15 @@
<footer class="article-footer"> <footer class="article-meta article-footer">
{{ partial "article/components/tags" . }} {{ partial "article/components/tags" . }}
{{ if and (.Site.Params.article.license.enabled) (not (eq .Params.license false)) }} {{ if and (.Site.Params.article.license.enabled) (not (eq .Params.license false)) }}
<section class="article-copyright"> <section class="article-copyright inline-meta">
{{ partial "helper/icon" "copyright" }} {{ partial "helper/icon" "copyright" }}
<span>{{ default .Site.Params.article.license.default .Params.license | markdownify }}</span> <span>{{ default .Site.Params.article.license.default .Params.license | markdownify }}</span>
</section> </section>
{{ end }} {{ end }}
{{- if ne .Lastmod .Date -}} {{- if ne .Lastmod .Date -}}
<section class="article-lastmod"> <section class="article-lastmod inline-meta">
{{ partial "helper/icon" "clock" }} {{ partial "helper/icon" "clock" }}
<span> <span>
{{ T "article.lastUpdatedOn" }} {{ .Lastmod | time.Format .Site.Params.dateFormat.lastUpdated }} {{ T "article.lastUpdatedOn" }} {{ .Lastmod | time.Format .Site.Params.dateFormat.lastUpdated }}
@@ -1,7 +1,7 @@
{{- $IsList := .IsList -}} {{- $IsList := .IsList -}}
{{- $Page := .Page -}} {{- $Page := .Page -}}
<header class="article-header"> <header class="article-header">
{{- $image := partial "helper/image" (dict "Image" $Page.Params.image "Resources" $Page.Resources) -}} {{- $image := partial "helper/image" (dict "Image" $Page.Params.image "Resources" $Page.Resources "Context" $Page) -}}
{{ if $image }} {{ if $image }}
<div class="article-image"> <div class="article-image">
<a href="{{ $Page.RelPermalink }}"> <a href="{{ $Page.RelPermalink }}">
@@ -6,7 +6,7 @@
<h2 class="article-title"> <h2 class="article-title">
{{- $link.title -}} {{- $link.title -}}
</h2> </h2>
<footer class="article-footer"> <footer class="article-meta">
{{ with $link.description }} {{ with $link.description }}
{{ . }} {{ . }}
{{ else }} {{ else }}
@@ -15,7 +15,7 @@
</footer> </footer>
</div> </div>
{{- $image := partial "helper/image" (dict "Image" $link.image "Resources" $.Resources) -}} {{- $image := partial "helper/image" (dict "Image" $link.image "Resources" $.Resources "Context" .) -}}
{{- with $image -}} {{- with $image -}}
<div class="article-image"> <div class="article-image">
{{ partial "helper/thumbnail-image" (dict {{ partial "helper/thumbnail-image" (dict
@@ -5,7 +5,7 @@
<div class="subsection-list"> <div class="subsection-list">
<div class="article-list--tile"> <div class="article-list--tile">
{{ range . }} {{ range . }}
{{ partial "article-list/tile" (dict "context" . "size" "250x150" "Type" "articleList") }} {{ partial "article-list/tile" . }}
{{ end }} {{ end }}
</div> </div>
</div> </div>
+1 -1
View File
@@ -23,7 +23,7 @@
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}"> <link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
{{- end -}} {{- end -}}
{{- $favicon := partial "helper/image" (dict "Image" .Site.Params.favicon "Resources" resources) -}} {{- $favicon := partial "helper/image" (dict "Image" .Site.Params.favicon "Resources" resources "Context" .) -}}
{{ with $favicon }} {{ with $favicon }}
<link rel="shortcut icon" href="{{ .Permalink }}" /> <link rel="shortcut icon" href="{{ .Permalink }}" />
{{ end }} {{ end }}
@@ -37,7 +37,7 @@
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{ $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) }} {{ $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources "Context" .) }}
{{- if $image -}} {{- if $image -}}
<meta property='og:image' content='{{ absURL $image.permalink }}' /> <meta property='og:image' content='{{ absURL $image.permalink }}' />
{{- end -}} {{- end -}}
@@ -9,7 +9,7 @@
<meta name="twitter:title" {{ printf "content=%q" $title | safeHTMLAttr }}> <meta name="twitter:title" {{ printf "content=%q" $title | safeHTMLAttr }}>
<meta name="twitter:description" {{ printf "content=%q" $description | safeHTMLAttr }}> <meta name="twitter:description" {{ printf "content=%q" $description | safeHTMLAttr }}>
{{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) -}} {{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources "Context" .) -}}
{{- if $image -}} {{- if $image -}}
<meta name="twitter:card" content="{{ .Site.Params.opengraph.twitter.card }}"> <meta name="twitter:card" content="{{ .Site.Params.opengraph.twitter.card }}">
<meta name="twitter:image" content='{{ absURL $image.permalink }}' /> <meta name="twitter:image" content='{{ absURL $image.permalink }}' />
+13 -2
View File
@@ -1,6 +1,7 @@
/// Params: /// Params:
/// Resources: Where to search for images /// Resources: Where to search for images
/// Image: Image URL /// Image: Image URL
/// Context: page context (used to access the configuration)
/// Returns: /// Returns:
/// Resource: Hugo image resource object /// Resource: Hugo image resource object
@@ -14,6 +15,7 @@
{{ $url := urls.Parse .Image }} {{ $url := urls.Parse .Image }}
{{ $permalink := .Image }} {{ $permalink := .Image }}
{{ $resource := "" }} {{ $resource := "" }}
{{ $local := true }}
{{ if not (in (slice "https" "http") $url.Scheme) }} {{ if not (in (slice "https" "http") $url.Scheme) }}
{{/* Local image */}} {{/* Local image */}}
@@ -26,14 +28,23 @@
{{ errorf "%s" . }} {{ errorf "%s" . }}
{{ else with .Value }} {{ else with .Value }}
{{ $resource = . }} {{ $resource = . }}
{{ $local = false }}
{{ else }} {{ else }}
{{ errorf "Unable to get remote resource %q" $url }} {{ errorf "Unable to get remote resource %q" $url }}
{{ end }} {{ end }}
{{ end }} {{ end }}
{{ end }} {{ end }}
{{ with $resource }} {{ if $resource }}
{{ if reflect.IsImageResourceWithMeta . }} {{ if and .Context.Site.Params.imageProcessing.autoOrient (reflect.IsImageResourceProcessable $resource) }}
{{ $filter := images.AutoOrient }}
{{ $resource = $resource | images.Filter $filter }}
{{ if $local }}
{{ $permalink = $resource.RelPermalink }}
{{ end }}
{{ end }}
{{ if reflect.IsImageResourceWithMeta $resource }}
{{ $result = dict {{ $result = dict
"Resource" $resource "Resource" $resource
"Permalink" $permalink "Permalink" $permalink
+1 -1
View File
@@ -7,7 +7,7 @@
<header> <header>
{{ with .Site.Params.sidebar.avatar }} {{ with .Site.Params.sidebar.avatar }}
{{- $avatar := partial "helper/image" (dict "Image" . "Resources" resources) -}} {{- $avatar := partial "helper/image" (dict "Image" . "Resources" resources "Context" $) -}}
<figure class="site-avatar"> <figure class="site-avatar">
<a href="{{ $.Site.Home.RelPermalink }}"> <a href="{{ $.Site.Home.RelPermalink }}">
<img src="{{ $avatar.Permalink }}" <img src="{{ $avatar.Permalink }}"
+1 -1
View File
@@ -8,7 +8,7 @@
<div class="subsection-list"> <div class="subsection-list">
<div class="article-list--tile"> <div class="article-list--tile">
{{ range $terms }} {{ range $terms }}
{{ partial "article-list/tile" (dict "context" . "size" "250x150" "Type" "taxonomy") }} {{ partial "article-list/tile" . }}
{{ end }} {{ end }}
</div> </div>
</div> </div>
+2 -2
View File
@@ -17,7 +17,7 @@
{{ end }} {{ end }}
</div> </div>
{{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) -}} {{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources "Context" .) -}}
{{ if $image }} {{ if $image }}
<div class="section-image"> <div class="section-image">
{{ partial "helper/thumbnail-image" (dict {{ partial "helper/thumbnail-image" (dict
@@ -51,7 +51,7 @@
<div class="subsection-list"> <div class="subsection-list">
<div class="article-list--tile"> <div class="article-list--tile">
{{ range . }} {{ range . }}
{{ partial "article-list/tile" (dict "context" . "size" "250x150" "Type" "section") }} {{ partial "article-list/tile" . }}
{{ end }} {{ end }}
</div> </div>
</div> </div>
+1 -1
View File
@@ -4,7 +4,7 @@
{{- range $pages -}} {{- range $pages -}}
{{- $data := dict "title" .Title "date" .Date "permalink" .RelPermalink "content" (.Plain) -}} {{- $data := dict "title" .Title "date" .Date "permalink" .RelPermalink "content" (.Plain) -}}
{{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) -}} {{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources "Context" .) -}}
{{- if $image -}} {{- if $image -}}
{{- $data = merge $data (dict "image" $image.Permalink) -}} {{- $data = merge $data (dict "image" $image.Permalink) -}}
{{- end -}} {{- end -}}
+1 -1
View File
@@ -50,7 +50,7 @@
{{- if .Site.Params.RSSFullContent -}} {{- if .Site.Params.RSSFullContent -}}
{{- $content = .Content -}} {{- $content = .Content -}}
{{- end -}} {{- end -}}
{{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources) -}} {{- $image := partial "helper/image" (dict "Image" .Params.image "Resources" .Resources "Context" .) -}}
{{- if $image -}} {{- if $image -}}
{{- $imgTag := printf "<img src=\"%s\" alt=\"Featured image of post %s\" />" ($image.permalink | absURL) .Title -}} {{- $imgTag := printf "<img src=\"%s\" alt=\"Featured image of post %s\" />" ($image.permalink | absURL) .Title -}}
{{- $content = printf "%s%s" $imgTag $content -}} {{- $content = printf "%s%s" $imgTag $content -}}