diff --git a/docs/website/overrides/main.html b/docs/website/overrides/main.html
index 2deccec..d2c539f 100644
--- a/docs/website/overrides/main.html
+++ b/docs/website/overrides/main.html
@@ -8,6 +8,6 @@
{% endif %}
{% endblock %}
-{% block announce %}
- Do you like our projects? Support us by following Ivan on GitHub!
-{% endblock %}
+
+
+
--
2.54.0
From 7eda841825abf928cde8473f561e22c8a0ed599e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?=
Date: Sun, 13 Apr 2025 12:19:48 +0200
Subject: [PATCH 2/4] build(website): Decrease the visibility of the 'news'
section in the site search
---
docs/website/generate-news.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/website/generate-news.sh b/docs/website/generate-news.sh
index d748dad..21b5723 100755
--- a/docs/website/generate-news.sh
+++ b/docs/website/generate-news.sh
@@ -7,7 +7,7 @@ for tag in $(git tag --list -n1 | cut -d' ' -f1); do
tag_file="docs/news/posts/releases/release-$tag.md"
git for-each-ref \
- --format="---%ndate:%n created: %(taggerdate:short)%nslug: v$tag%ntags: %n - Releases%n---%n%n# $tag • %(subject)%n%n%(contents:body)" \
+ --format="---%ndate:%n created: %(taggerdate:short)%nsearch:%n boost: 0.25%nslug: v$tag%ntags: %n - Releases%n---%n%n# $tag • %(subject)%n%n%(contents:body)" \
"refs/tags/$tag" \
| sed 's/%n/\n/g' \
| sed -r "s~\#([0-9]+)~[#\1]($CI_PROJECT_URL/-/issues/\1)~g" \
--
2.54.0
From 5aafb5e372245c289ae173df153f9c97f3a19456 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?=
Date: Sun, 22 Mar 2026 12:59:29 +0100
Subject: [PATCH 3/4] feat(website): Display the full page title in social
images
---
docs/website/layouts/default.yml | 257 +++++++++++++++++++++++++++++++
1 file changed, 257 insertions(+)
create mode 100644 docs/website/layouts/default.yml
diff --git a/docs/website/layouts/default.yml b/docs/website/layouts/default.yml
new file mode 100644
index 0000000..7b997ac
--- /dev/null
+++ b/docs/website/layouts/default.yml
@@ -0,0 +1,257 @@
+# Copyright (c) 2016-2025 Martin Donath
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+# -----------------------------------------------------------------------------
+# Configuration
+# -----------------------------------------------------------------------------
+
+# Definitions
+definitions:
+
+ # Background image
+ - &background_image >-
+ {{ layout.background_image | x }}
+
+ # Background color (default: indigo)
+ - &background_color >-
+ {%- if layout.background_color -%}
+ {{ layout.background_color }}
+ {%- else -%}
+ {%- set palette = config.theme.palette or {} -%}
+ {%- if not palette is mapping -%}
+ {%- set list = palette | selectattr("primary") | list + palette -%}
+ {%- set palette = list | first -%}
+ {%- endif -%}
+ {%- set primary = palette.get("primary", "indigo") -%}
+ {%- set primary = primary.replace(" ", "-") -%}
+ {{ {
+ "red": "#ef5552",
+ "pink": "#e92063",
+ "purple": "#ab47bd",
+ "deep-purple": "#7e56c2",
+ "indigo": "#4051b5",
+ "blue": "#2094f3",
+ "light-blue": "#02a6f2",
+ "cyan": "#00bdd6",
+ "teal": "#009485",
+ "green": "#4cae4f",
+ "light-green": "#8bc34b",
+ "lime": "#cbdc38",
+ "yellow": "#ffec3d",
+ "amber": "#ffc105",
+ "orange": "#ffa724",
+ "deep-orange": "#ff6e42",
+ "brown": "#795649",
+ "grey": "#757575",
+ "blue-grey": "#546d78",
+ "black": "#000000",
+ "white": "#ffffff"
+ }[primary] or "#4051b5" }}
+ {%- endif -%}
+
+ # Text color (default: white)
+ - &color >-
+ {%- if layout.color -%}
+ {{ layout.color }}
+ {%- else -%}
+ {%- set palette = config.theme.palette or {} -%}
+ {%- if not palette is mapping -%}
+ {%- set list = palette | selectattr("primary") | list + palette -%}
+ {%- set palette = list | first -%}
+ {%- endif -%}
+ {%- set primary = palette.get("primary", "indigo") -%}
+ {%- set primary = primary.replace(" ", "-") -%}
+ {{ {
+ "red": "#ffffff",
+ "pink": "#ffffff",
+ "purple": "#ffffff",
+ "deep-purple": "#ffffff",
+ "indigo": "#ffffff",
+ "blue": "#ffffff",
+ "light-blue": "#ffffff",
+ "cyan": "#ffffff",
+ "teal": "#ffffff",
+ "green": "#ffffff",
+ "light-green": "#ffffff",
+ "lime": "#000000",
+ "yellow": "#000000",
+ "amber": "#000000",
+ "orange": "#000000",
+ "deep-orange": "#ffffff",
+ "brown": "#ffffff",
+ "grey": "#ffffff",
+ "blue-grey": "#ffffff",
+ "black": "#ffffff",
+ "white": "#000000"
+ }[primary] or "#ffffff" }}
+ {%- endif -%}
+
+ # Font family (default: Roboto)
+ - &font_family >-
+ {%- if layout.font_family -%}
+ {{ layout.font_family }}
+ {%- elif config.theme.font is mapping -%}
+ {{ config.theme.font.get("text", "Roboto") }}
+ {%- else -%}
+ Roboto
+ {%- endif -%}
+
+ # Font variant
+ - &font_variant >-
+ {%- if layout.font_variant -%}
+ {{ layout.font_variant }}
+ {%- endif -%}
+
+ # Site name
+ - &site_name >-
+ {{ config.site_name }}
+
+ # Page title
+ #
+ # Modified by OpenSavvy: prefer the page's first heading over the (possibly
+ # short) navigation title, matching overrides/main.html's tag logic.
+ - &page_title >-
+ {%- if layout.title -%}
+ {{ layout.title }}
+ {%- elif page.toc | first is defined -%}
+ {{ page.toc.items[0].title }}
+ {%- else -%}
+ {{ page.meta.get("title", page.title) }}
+ {%- endif -%}
+
+ # Page title with site name
+ #
+ # Modified by OpenSavvy: prefer the page's first heading over the (possibly
+ # short) navigation title, matching overrides/main.html's tag logic.
+ - &page_title_with_site_name >-
+ {%- if not page.is_homepage -%}
+ {%- if page.toc | first is defined -%}
+ {%- set title = page.toc.items[0].title -%}
+ {%- else -%}
+ {%- set title = page.meta.get("title", page.title) -%}
+ {%- endif -%}
+ {{ title }} - {{ config.site_name }}
+ {%- else -%}
+ {{ config.site_name }}
+ {%- endif -%}
+
+ # Page description
+ - &page_description >-
+ {%- if layout.description -%}
+ {{ layout.description }}
+ {%- else -%}
+ {{ page.meta.get("description", config.site_description) | x }}
+ {%- endif -%}
+
+ # Logo
+ - &logo >-
+ {%- if layout.logo -%}
+ {{ layout.logo }}
+ {%- elif config.theme.logo -%}
+ {{ config.docs_dir }}/{{ config.theme.logo }}
+ {%- endif -%}
+
+ # Logo (icon)
+ - &logo_icon >-
+ {%- if not layout.logo and config.theme.icon -%}
+ {{ config.theme.icon.logo | x }}
+ {%- endif -%}
+
+# Meta tags
+tags:
+
+ # Open Graph
+ og:type: website
+ og:title: *page_title_with_site_name
+ og:description: *page_description
+ og:image: "{{ image.url }}"
+ og:image:type: "{{ image.type }}"
+ og:image:width: "{{ image.width }}"
+ og:image:height: "{{ image.height }}"
+ og:url: "{{ page.canonical_url }}"
+
+ # Twitter
+ twitter:card: summary_large_image
+ twitter:title: *page_title_with_site_name
+ twitter:description: *page_description
+ twitter:image: "{{ image.url }}"
+
+# -----------------------------------------------------------------------------
+# Specification
+# -----------------------------------------------------------------------------
+
+# Card size and layers
+size: { width: 1200, height: 630 }
+layers:
+
+ # Background
+ - background:
+ image: *background_image
+ color: *background_color
+
+ # Logo
+ - size: { width: 144, height: 144 }
+ offset: { x: 992, y: 64 }
+ background:
+ image: *logo
+ icon:
+ value: *logo_icon
+ color: *color
+
+ # Site name
+ - size: { width: 832, height: 42 }
+ offset: { x: 64, y: 64 }
+ typography:
+ content: *site_name
+ color: *color
+ font:
+ family: *font_family
+ variant: *font_variant
+ style: Bold
+
+ # Page title
+ - size: { width: 832, height: 310 }
+ offset: { x: 62, y: 160 }
+ typography:
+ content: *page_title
+ align: start
+ color: *color
+ line:
+ amount: 3
+ height: 1.25
+ font:
+ family: *font_family
+ variant: *font_variant
+ style: Bold
+
+ # Page description
+ - size: { width: 832, height: 64 }
+ offset: { x: 64, y: 512 }
+ typography:
+ content: *page_description
+ align: start
+ color: *color
+ line:
+ amount: 2
+ height: 1.5
+ font:
+ family: *font_family
+ variant: *font_variant
+ style: Regular
--
2.54.0
From 5b9e6634e4e7ebf686eccfd064947b3739cab4b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ivan=20=E2=80=9CCLOVIS=E2=80=9D=20Canet?=
Date: Thu, 2 Jul 2026 09:37:37 +0200
Subject: [PATCH 4/4] ci(gitlab): OpenSavvy Containers 0.8.10
---
.gitlab-ci.main.kts | 2 +-
.gitlab-ci.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.gitlab-ci.main.kts b/.gitlab-ci.main.kts
index 07b3bb3..90a0bd8 100755
--- a/.gitlab-ci.main.kts
+++ b/.gitlab-ci.main.kts
@@ -10,7 +10,7 @@ import opensavvy.gitlab.ci.script.shell
/**
* [OpenSavvy's CI container images](https://gitlab.com/opensavvy/automation/containers/-/releases)
*/
-val ciContainers = "0.8.7"
+val ciContainers = "0.8.10"
/**
* The URL of the website built by /docs/website.
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8e7e36b..17fb572 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -10,7 +10,7 @@ include:
variables:
# https://gitlab.com/opensavvy/automation/containers
- ci_containers: 0.8.7
+ ci_containers: 0.8.10
workflow:
rules: