From 1160242e7238cc69aadba9f7dff064b4ccf0a1d7 Mon Sep 17 00:00:00 2001
From: Richard Dern
Date: Fri, 3 Apr 2026 00:17:38 +0200
Subject: [PATCH] Ajoute les articles relatifs et harmonise la page 404
---
config/_default/related.yaml | 24 +++
themes/2026/assets/css/content.css | 142 +++++++++++++++++-
themes/2026/layouts/404.html | 32 +++-
.../layouts/_partials/article-header.html | 50 +++---
.../layouts/_partials/article-related.html | 53 +++++++
themes/2026/layouts/page.html | 1 +
6 files changed, 275 insertions(+), 27 deletions(-)
create mode 100644 config/_default/related.yaml
create mode 100644 themes/2026/layouts/_partials/article-related.html
diff --git a/config/_default/related.yaml b/config/_default/related.yaml
new file mode 100644
index 00000000..9195cfdf
--- /dev/null
+++ b/config/_default/related.yaml
@@ -0,0 +1,24 @@
+includeNewer: true
+threshold: 10
+toLower: true
+indices:
+ - name: oeuvres
+ weight: 120
+ - name: franchises
+ weight: 110
+ - name: tags
+ cardinalityThreshold: 5
+ weight: 100
+ - name: keywords
+ cardinalityThreshold: 5
+ weight: 90
+ - name: genres
+ weight: 80
+ - name: personnages_de_fiction
+ weight: 70
+ - name: personnalites
+ weight: 60
+ - name: animaux
+ weight: 20
+ - name: entreprises
+ weight: 20
diff --git a/themes/2026/assets/css/content.css b/themes/2026/assets/css/content.css
index eb896243..2fc40174 100644
--- a/themes/2026/assets/css/content.css
+++ b/themes/2026/assets/css/content.css
@@ -131,7 +131,7 @@ body > main:has(> article:first-child):has(> aside) > article:first-child {
line-height: 1.85;
}
-body > main:has(> article:first-child):has(> aside) > article:first-child > :not(figure):not(table):not(pre):not(.highlight):not(section.article-books) {
+body > main:has(> article:first-child):has(> aside) > article:first-child > :not(figure):not(table):not(pre):not(.highlight):not(section.article-books):not(section.article-related) {
max-width: 74ch;
}
@@ -303,6 +303,146 @@ main > article li + li {
margin-top: 0.35rem;
}
+main > article > section.article-related {
+ margin-top: var(--space-6);
+ border-top: 1px solid var(--color-border);
+ padding-top: var(--space-4);
+}
+
+main > article > section.article-related > header {
+ margin-top: 0;
+}
+
+main > article > section.article-related > header > h2 {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 0;
+ font-size: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+}
+
+main > article > section.article-related > header > h2::before {
+ display: none;
+}
+
+main > article > section.article-related > nav.articles-list {
+ --articles-related-flow-gap: 0.72rem;
+ margin-top: var(--space-3);
+}
+
+main > article > section.article-related > nav.articles-list > ol {
+ padding-left: 0;
+ grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
+ gap: var(--space-4);
+}
+
+main > article > section.article-related > nav.articles-list > ol > li,
+main > article > section.article-related > nav.articles-list > ol > li + li {
+ margin-top: 0;
+}
+
+main > article > section.article-related > nav.articles-list article {
+ border-top: 0;
+ padding-top: 0;
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header {
+ margin-top: 0;
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header > a {
+ display: block;
+ color: inherit;
+ text-decoration: none;
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header > a > figure {
+ margin: 0;
+ min-height: 0;
+ aspect-ratio: 340 / 191;
+ overflow: hidden;
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header > a > figure img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header > p {
+ margin-top: var(--articles-related-flow-gap);
+ font-size: 0.78rem;
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
+ color: var(--color-text-muted);
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header > p > a {
+ color: inherit;
+ text-decoration: none;
+ font-family: var(--font-heading);
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header > p > a:is(:hover, :focus-visible) {
+ color: var(--color-link-hover);
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header > h3 {
+ margin-top: var(--articles-related-flow-gap);
+ margin-bottom: 0;
+ padding-top: 0;
+ position: static;
+ font-size: clamp(1rem, 1.5vw, 1.12rem);
+ line-height: 1.15;
+ text-transform: none;
+ letter-spacing: 0.01em;
+ color: var(--color-heading);
+ font-weight: 400;
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header > h3::before {
+ display: none;
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header > h3 > a {
+ color: var(--color-heading);
+ text-decoration: none;
+}
+
+main > article > section.article-related > nav.articles-list > ol > li article > header:has(> p) > h3 {
+ margin-top: calc(var(--articles-related-flow-gap) * 0.4);
+}
+
+main > article > section.article-related > nav.articles-list article > p:nth-of-type(1) {
+ display: none;
+}
+
+main > article > section.article-related > nav.articles-list article > p:last-child {
+ margin-top: var(--articles-related-flow-gap);
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-1);
+ font-size: 0.76rem;
+ color: var(--color-text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+ font-family: var(--font-heading);
+}
+
+main > article > section.article-related > nav.articles-list article > p:last-child > a {
+ color: inherit;
+ text-decoration: underline;
+ text-decoration-thickness: 1px;
+ text-underline-offset: 0.15em;
+}
+
+main > article > section.article-related > nav.articles-list article > p:last-child > a:is(:hover, :focus-visible) {
+ color: inherit;
+ filter: brightness(1.2);
+}
+
main > article > footer.article-footer {
margin-top: var(--space-6);
border-top: 1px solid var(--color-border);
diff --git a/themes/2026/layouts/404.html b/themes/2026/layouts/404.html
index 92217af6..15c83d0c 100644
--- a/themes/2026/layouts/404.html
+++ b/themes/2026/layouts/404.html
@@ -1,9 +1,15 @@
{{ define "main" }}
-{{- $recentPages := first 6 (site.RegularPages.ByDate.Reverse) -}}
-
- {{ partialCached "header-brand.html" .Site .Site.Title (.Site.Params.logo | default "logo-large.png") }}
- Page introuvable
-
+{{- $recentPages := slice -}}
+{{- range site.RegularPages.ByDate.Reverse -}}
+ {{- if and .Params.date (lt (len $recentPages) 8) -}}
+ {{- $recentPages = $recentPages | append . -}}
+ {{- end -}}
+{{- end -}}
+{{ partial "article-header.html" (dict
+ "Page" .
+ "Title" "Page introuvable"
+ "ShowMeta" false
+) }}
Le contenu que vous recherchez n'existe pas.
@@ -11,9 +17,19 @@
{{ if gt (len $recentPages) 0 }}
-
-
- {{ partial "articles-list.html" (dict "Pages" $recentPages "Context" .) }}
+
+
+ {{ partial "spotlight-block.html" (dict
+ "Cards" $recentPages
+ "FeedPages" $recentPages
+ "FeedTitle" "Derniers articles"
+ "ShowFeedTitle" false
+ "FeedRich" true
+ "ShowSection" true
+ "AsideFirst" false
+ ) }}
{{ end }}
diff --git a/themes/2026/layouts/_partials/article-header.html b/themes/2026/layouts/_partials/article-header.html
index 7ff23446..e0e51bcc 100644
--- a/themes/2026/layouts/_partials/article-header.html
+++ b/themes/2026/layouts/_partials/article-header.html
@@ -1,8 +1,22 @@
-{{- $page := .Page -}}
-{{- $coverPath := .Params.cover -}}
-{{- $isInterestingLink := strings.HasPrefix .RelPermalink "/interets/liens-interessants/" -}}
+{{- $page := . -}}
+{{- $title := .Title -}}
+{{- $showMeta := true -}}
+{{- if reflect.IsMap . -}}
+ {{- with index . "Page" -}}
+ {{- $page = . -}}
+ {{- end -}}
+ {{- with index . "Title" -}}
+ {{- $title = . -}}
+ {{- end -}}
+ {{- if isset . "ShowMeta" -}}
+ {{- $showMeta = index . "ShowMeta" -}}
+ {{- end -}}
+{{- end -}}
+
+{{- $coverPath := $page.Params.cover -}}
+{{- $isInterestingLink := strings.HasPrefix $page.RelPermalink "/interets/liens-interessants/" -}}
{{- $showCover := and $coverPath (not $isInterestingLink) -}}
-{{- $linksParam := .Params.links -}}
+{{- $linksParam := $page.Params.links -}}
{{- $links := slice -}}
{{- if $linksParam -}}
{{- $type := printf "%T" $linksParam -}}
@@ -105,17 +119,17 @@
{{- end -}}
{{- end -}}
-{{- $coverImageTitle := default .Title (index $coverData "title") -}}
+{{- $coverImageTitle := default $title (index $coverData "title") -}}
{{- $coverTitle := index $coverData "title" -}}
{{- $coverDescription := index $coverData "description" -}}
{{- $coverAttribution := index $coverData "attribution" -}}
{{- $coverPrompt := index $coverData "prompt" -}}
-{{- $weather := .Params.weather -}}
+{{- $weather := $page.Params.weather -}}
{{- $weatherIcon := "" -}}
{{- $weatherLabel := "Météo" -}}
{{- $weatherTitle := "" -}}
{{- if and $weather (gt (len $weather) 0) -}}
- {{- $hour := (time .Date).Hour -}}
+ {{- $hour := (time $page.Date).Hour -}}
{{- $isNight := false -}}
{{- if or (lt $hour 6) (ge $hour 18) -}}
{{- $isNight = true -}}
@@ -169,15 +183,15 @@
{{- end -}}
{{- $hasCoverImage := and $showCover $coverImage -}}
{{- $hasCoverMeta := or $coverTitle $coverDescription $coverAttribution $coverPrompt -}}
-{{- $showReadingTime := ge .ReadingTime 5 -}}
+{{- $showReadingTime := ge $page.ReadingTime 5 -}}
{{- $hasPublication := or $showReadingTime $hasWeatherIcon -}}
-{{- with .Date -}}
+{{- with $page.Date -}}
{{- $hasPublication = true -}}
{{- end -}}
-{{- $breadcrumbsMarkup := partial "breadcrumbs.html" . -}}
+{{- $breadcrumbsMarkup := partial "breadcrumbs.html" $page -}}
{{- $hasBreadcrumbs := ne (strings.TrimSpace $breadcrumbsMarkup) "" -}}
{{- $pageLinksMarkup := partial "page-links.html" (dict
- "Page" .
+ "Page" $page
"LinkClass" "ui-button"
"Links" $remainingLinks
) -}}
@@ -185,11 +199,11 @@
{{- $hasOriginCallout := and $isInterestingLink (ne $originURL "") -}}
{{- $hasMetaMain := or $hasBreadcrumbs $hasPublication $hasPageLinks $hasOriginCallout -}}
{{- $showCoverMeta := and (not $isInterestingLink) $coverPath $hasCoverMeta -}}
-{{- $hasMetaBlock := or $hasCoverImage $hasMetaMain $showCoverMeta -}}
+{{- $hasMetaBlock := and $showMeta (or $hasCoverImage $hasMetaMain $showCoverMeta) -}}
- {{ partialCached "header-brand.html" .Site .Site.Title (.Site.Params.logo | default "logo-large.png") }}
- {{ .Title }}
+ {{ partialCached "header-brand.html" $page.Site $page.Site.Title ($page.Site.Params.logo | default "logo-large.png") }}
+ {{ $title }}
{{- if $hasMetaBlock -}}
@@ -209,7 +223,7 @@
{{- if $hasPublication -}}
- {{ with .Date }}
+ {{ with $page.Date }}
{{- $timePart := . | time.Format "15:04:05" -}}
{{- end -}}
@@ -244,7 +258,7 @@
"Title" "Lire la page d'origine"
"Text" $originLinkText
"Class" "ui-button article-origin-link-button-link"
- "Page" .
+ "Page" $page
) -}}
@@ -266,7 +280,7 @@
{{- end -}}
{{- with $coverAttribution -}}
{{- $attribution := partial "media/parse-attribution.html" . -}}
- Attribution: {{- if index $attribution "isURL" -}}{{ partial "render/link.html" (dict "Destination" (index $attribution "url") "Page" $ "Text" (index $attribution "label")) }}{{- else -}}{{ . | markdownify }}{{- end -}}
+ Attribution: {{- if index $attribution "isURL" -}}{{ partial "render/link.html" (dict "Destination" (index $attribution "url") "Page" $page "Text" (index $attribution "label")) }}{{- else -}}{{ . | markdownify }}{{- end -}}
{{- end -}}
{{- with $coverPrompt -}}
diff --git a/themes/2026/layouts/_partials/article-related.html b/themes/2026/layouts/_partials/article-related.html
new file mode 100644
index 00000000..4e830f1c
--- /dev/null
+++ b/themes/2026/layouts/_partials/article-related.html
@@ -0,0 +1,53 @@
+{{- $excludePrefix := "interets/liens-interessants/" -}}
+{{- $excludeCurrent := false -}}
+{{- $currentHasDate := false -}}
+{{- with .File -}}
+ {{- if strings.HasPrefix .Path $excludePrefix -}}
+ {{- $excludeCurrent = true -}}
+ {{- end -}}
+{{- end -}}
+{{- with .Params.date -}}
+ {{- $currentHasDate = true -}}
+{{- end -}}
+{{- if not $currentHasDate -}}
+ {{- $excludeCurrent = true -}}
+{{- end -}}
+
+{{- if not $excludeCurrent -}}
+{{- $related := site.RegularPages.Related . -}}
+{{- $items := slice -}}
+{{- range $related -}}
+ {{- $excludeCandidate := false -}}
+ {{- $sameDossier := false -}}
+ {{- $candidateHasDate := false -}}
+ {{- with .File -}}
+ {{- if strings.HasPrefix .Path $excludePrefix -}}
+ {{- $excludeCandidate = true -}}
+ {{- end -}}
+ {{- end -}}
+ {{- with .Params.date -}}
+ {{- $candidateHasDate = true -}}
+ {{- end -}}
+ {{- if gt (len (intersect (default (slice) $.Params.dossier) (default (slice) .Params.dossier))) 0 -}}
+ {{- $sameDossier = true -}}
+ {{- end -}}
+ {{- if and $candidateHasDate (not $excludeCandidate) (not $sameDossier) (ne .RelPermalink $.RelPermalink) -}}
+ {{- $items = $items | append . -}}
+ {{- end -}}
+ {{- if ge (len $items) 3 -}}
+ {{- break -}}
+ {{- end -}}
+{{- end -}}
+
+{{- if gt (len $items) 0 -}}
+
+
+ {{- partial "articles-list.html" (dict
+ "Pages" $items
+ "ShowDossierBeforeTitle" true
+ ) -}}
+
+{{- end -}}
+{{- end -}}
diff --git a/themes/2026/layouts/page.html b/themes/2026/layouts/page.html
index e21ae644..cc550a05 100644
--- a/themes/2026/layouts/page.html
+++ b/themes/2026/layouts/page.html
@@ -5,6 +5,7 @@
{{ .Content }}
{{ partial "article-books.html" . }}
{{ partial "article-asides.html" . }}
+ {{ partial "article-related.html" . }}
{{ partial "article-footer.html" . }}
{{ partial "asides/complementary-images.html" . }}