From df489c6c79bda074d70ffa8feb5201d18c5c654d Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 11 Aug 2026 12:25:14 +0200 Subject: [PATCH] Add language switcher and language detection --- hugo.toml | 388 ++++++++++-------- .../chill-theme/layouts/_default/baseof.html | 24 +- .../baseof.html.tmp.929740.f1c11cc9c42b | 131 ++++++ .../chill-theme/layouts/partials/footer.html | 4 +- .../chill-theme/layouts/partials/header.html | 16 +- .../layouts/partials/language-detection.html | 106 +++++ .../partials/language-switcher-mobile.html | 24 ++ .../layouts/partials/language-switcher.html | 28 +- .../layouts/partials/shortcodes/carousel.html | 4 +- .../layouts/shortcodes/contact-form.html | 2 +- .../static/js/language-preference.js | 183 --------- 11 files changed, 526 insertions(+), 384 deletions(-) create mode 100644 themes/chill-theme/layouts/_default/baseof.html.tmp.929740.f1c11cc9c42b create mode 100644 themes/chill-theme/layouts/partials/language-detection.html create mode 100644 themes/chill-theme/layouts/partials/language-switcher-mobile.html delete mode 100644 themes/chill-theme/static/js/language-preference.js diff --git a/hugo.toml b/hugo.toml index f483437..bbde777 100644 --- a/hugo.toml +++ b/hugo.toml @@ -3,26 +3,7 @@ baseURL = "/" title = "" theme = "chill-theme" defaultContentLanguage = "fr" -disableLanguages = ["en", "nl"] - -# Language configuration -[languages] - [languages.fr] - languageCode = "fr-fr" - languageName = "Français" - weight = 1 - contentDir = "content" - - [languages.en] - languageCode = "en-us" - languageName = "English" - weight = 2 - contentDir = "content/en" - [languages.nl] - languageCode = "nl-nl" - languageName = "Nederlands" - weight = 3 - contentDir = "content/nl" +defaultContentLanguageInSubdir = false # Required Features enableEmoji = true # Enable emoji support @@ -69,14 +50,13 @@ pagination = { pagerSize = 6, path = "page" } category = 'categories' tag = 'tags' -# Theme Parameters +# Theme Parameters shared by every language. +# Anything language specific lives under [languages..params] below. [params] - description = "Logiciel libre d'accompagnement social" author = "Champs-Libres" logo = "/images/logo-darkmode.png" # Path to your logo customCSS = ["css/custom.css"] - # Header Configuration [params.header] background = "header backdrop-blur-sm" @@ -84,7 +64,6 @@ pagination = { pagerSize = 6, path = "page" } menu.linkClass = "text-white hover:text-primary font-bold transition duration-200" [params.header.buttons.demo] - text = "Démo" url = "http://demo.chill.social/" mobileClass = "block text-center px-6 py-3 rounded-lg font-bold transition duration-200 ease-in-out bg-primary-400 text-white hover:bg-primary-400 hover:scale-105" open_tab = true @@ -93,154 +72,239 @@ pagination = { pagerSize = 6, path = "page" } [params.header.logo] src = "/images/logo-darkmode.png" - [params.pdfFolder] - name = "Voir la brochure CHILL" - filename = "Brochure_Chill.pdf" - url = "/pdf/Brochure_Chill.pdf" - # Global CTA Configuration (optional) [params.cta] - enable = true - title = "Prêt·e à commencer ?" - description = "Testez Chill dès aujourd'hui et découvrez comment il peut transformer votre gestion sociale." + enable = true - # Gradient background - gradient_from = "#0d242e" # Blue-600 - gradient_to = "#23627e" # Purple-600 - gradient_angle = 30 + # Gradient background + gradient_from = "#0d242e" # Blue-600 + gradient_to = "#23627e" # Purple-600 + gradient_angle = 30 - # Primary button - [params.cta.primary_button] - text = "Réserver une démo" - url = "/contact?subject=demo" - open_tab = false - - # Secondary button - [params.cta.secondary_button] - text = "Essayer la démo" - url = "http://demo.chill.social/" - open_tab = true # Social Media Links (optional) [params.social] gitlab = "https://gitlab.com/Chill-Projet/chill-bundles" -# Navigation Menu -[menu] - [[menu.main]] - name = "Fonctionnalités" - url = "/features" - weight = 1 - [[menu.main]] - name = "Secteur d'activités" - weight = 2 - url = "/sector" - [menu.main.params] - has_submenu = true - submenu = [ - { name = "Grandes Collectivités", url = "/sector/collectivities" }, - { name = "Services et associations", url = "/sector/associations" }, - ] - [[menu.main]] - name = "Tarification" - url = "/pricing" - weight = 3 - [[menu.main]] - name = "Ressources" - weight = 4 - [menu.main.params] - has_submenu = true - submenu = [ - # { name = "Blog", url = "/resources/blog" }, - { name = "Manuels", url = "/resources/manuals" }, - { name = "Tutoriels", url = "/resources/tutorials" }, - { name = "Installation", url = "/resources/installation" }, - { name = "Documentation technique", url = "/resources/technical-documentation" }, - { name = "FAQ", url = "/resources/faq" } - ] - [[menu.main]] - name = "Nous contacter" - url = "/contact" - weight = 5 - [[menu.footer_column]] - name = "Champs-Libres" - url = "https://www.champs-libres.coop/" - weight = 1 + + +# --------------------------------------------------------------------------- +# Languages +# French is the default language and is served from the site root ("/"), +# English lives under "/en/" and Dutch under "/nl/". +# --------------------------------------------------------------------------- +[languages] + +# ------------------------------- Français ---------------------------------- +[languages.fr] + languageCode = "fr-fr" + languageName = "Français" + weight = 1 + contentDir = "content/fr" + + [languages.fr.params] + description = "Logiciel libre d'accompagnement social" + + [languages.fr.params.header.buttons.demo] + text = "Démo" + + [languages.fr.params.pdfFolder] + name = "Voir la brochure CHILL" + filename = "Brochure_Chill.pdf" + url = "/pdf/Brochure_Chill.pdf" + + [languages.fr.params.cta] + title = "Prêt·e à commencer ?" + description = "Testez Chill dès aujourd'hui et découvrez comment il peut transformer votre gestion sociale." + [languages.fr.params.cta.primary_button] + text = "Réserver une démo" + url = "/contact?subject=demo" + open_tab = false + [languages.fr.params.cta.secondary_button] + text = "Essayer la démo" + url = "http://demo.chill.social/" + open_tab = true + + [languages.fr.menu] + [[languages.fr.menu.main]] + name = "Fonctionnalités" + url = "/features" + weight = 1 + [[languages.fr.menu.main]] + name = "Secteur d'activités" + url = "/sector" + weight = 2 + [languages.fr.menu.main.params] + has_submenu = true + submenu = [ + { name = "Grandes Collectivités", url = "/sector/collectivities" }, + { name = "Services et associations", url = "/sector/associations" }, + ] + [[languages.fr.menu.main]] + name = "Tarification" + url = "/pricing" + weight = 3 + [[languages.fr.menu.main]] + name = "Ressources" + weight = 4 + [languages.fr.menu.main.params] + has_submenu = true + submenu = [ + # { name = "Blog", url = "/resources/blog" }, + { name = "Manuels", url = "/resources/manuals" }, + { name = "Tutoriels", url = "/resources/tutorials" }, + { name = "Installation", url = "/resources/installation" }, + { name = "Documentation technique", url = "/resources/technical-documentation" }, + { name = "FAQ", url = "/resources/faq" } + ] + [[languages.fr.menu.main]] + name = "Nous contacter" + url = "/contact" + weight = 5 + + [[languages.fr.menu.footer_column]] + name = "Champs-Libres" + url = "https://www.champs-libres.coop/" + weight = 1 + +# ------------------------------- English ----------------------------------- +[languages.en] + languageCode = "en-us" + languageName = "English" + weight = 2 + contentDir = "content/en" + + [languages.en.params] + description = "Free and open source software for social work" + + [languages.en.params.header.buttons.demo] + text = "Demo" + + [languages.en.params.pdfFolder] + name = "See the CHILL brochure" + filename = "Brochure_Chill.pdf" + url = "/pdf/Brochure_Chill.pdf" + + [languages.en.params.cta] + title = "Ready to get started?" + description = "Try Chill today and discover how it can transform the way you manage social support." + [languages.en.params.cta.primary_button] + text = "Book a demo" + url = "/en/contact?subject=demo" + open_tab = false + [languages.en.params.cta.secondary_button] + text = "Try the demo" + url = "http://demo.chill.social/" + open_tab = true [languages.en.menu] - [[languages.en.menu.main]] - name = "Features" - url = "/features" - weight = 1 - [[languages.en.menu.main]] - name = "Installation" - weight = 2 - [languages.en.menu.main.params] - has_submenu = true - submenu = [ - { name = "By Champs Libres", url = "/install/hosted" }, - { name = "Self-hosted", url = "/install/on-premise" } - ] - [[languages.en.menu.main]] - name = "Pricing" - url = "/pricing" - weight = 3 - [[languages.en.menu.main]] - name = "Resources" - weight = 4 - [languages.en.menu.main.params] - has_submenu = true - submenu = [ - # { name = "Blog", url = "/resources/blog" }, - { name = "Technical Documentation", url = "/resources/technical-documentation" }, - { name = "Manuals", url = "/resources/manuals" }, - { name = "Tutorials", url = "/resources/tutorials" }, - { name = "FAQ", url = "/resources/faq" } - ] - [[languages.en.menu.main]] - name = "Contact Us" - url = "/contact" - weight = 5 + [[languages.en.menu.main]] + name = "Features" + url = "/en/features" + weight = 1 + [[languages.en.menu.main]] + name = "Sectors" + url = "/en/sector" + weight = 2 + [languages.en.menu.main.params] + has_submenu = true + submenu = [ + { name = "Large local authorities", url = "/en/sector/collectivities" }, + { name = "Services and non-profits", url = "/en/sector/associations" }, + ] + [[languages.en.menu.main]] + name = "Pricing" + url = "/en/pricing" + weight = 3 + [[languages.en.menu.main]] + name = "Resources" + weight = 4 + [languages.en.menu.main.params] + has_submenu = true + submenu = [ + # { name = "Blog", url = "/en/resources/blog" }, + { name = "Manuals", url = "/en/resources/manuals" }, + { name = "Tutorials", url = "/en/resources/tutorials" }, + { name = "Installation", url = "/en/resources/installation" }, + { name = "Technical documentation", url = "/en/resources/technical-documentation" }, + { name = "FAQ", url = "/en/resources/faq" } + ] + [[languages.en.menu.main]] + name = "Contact us" + url = "/en/contact" + weight = 5 - [[languages.en.menu.footer_column_1]] - name = "Download the CHILL brochure" - url = "/pdf/Brochure_Chill.pdf" - weight = 1 + [[languages.en.menu.footer_column]] + name = "Champs-Libres" + url = "https://www.champs-libres.coop/" + weight = 1 + +# ------------------------------ Nederlands --------------------------------- +[languages.nl] + languageCode = "nl-nl" + languageName = "Nederlands" + weight = 3 + contentDir = "content/nl" + + [languages.nl.params] + description = "Vrije en opensource software voor maatschappelijk werk" + + [languages.nl.params.header.buttons.demo] + text = "Demo" + + [languages.nl.params.pdfFolder] + name = "Bekijk de CHILL-brochure" + filename = "Brochure_Chill.pdf" + url = "/pdf/Brochure_Chill.pdf" + + [languages.nl.params.cta] + title = "Klaar om te starten?" + description = "Probeer Chill vandaag nog en ontdek hoe het uw sociale begeleiding kan transformeren." + [languages.nl.params.cta.primary_button] + text = "Een demo boeken" + url = "/nl/contact?subject=demo" + open_tab = false + [languages.nl.params.cta.secondary_button] + text = "De demo uitproberen" + url = "http://demo.chill.social/" + open_tab = true [languages.nl.menu] - [[languages.nl.menu.main]] - name = "Functies" - url = "/features" - weight = 1 - [[languages.nl.menu.main]] - name = "Installatie" - weight = 2 - [languages.nl.menu.main.params] - has_submenu = true - submenu = [ - { name = "Door Champs Libres", url = "/install/hosted" }, - { name = "Zelf gehost", url = "/install/on-premise" } - ] - [[languages.nl.menu.main]] - name = "Prijsstelling" - url = "/pricing" - weight = 3 - [[languages.nl.menu.main]] - name = "Bronnen" - weight = 4 - [languages.nl.menu.main.params] - has_submenu = true - submenu = [ - { name = "Technische Documentatie", url = "/resources/technical-documentation" }, - { name = "Handleidingen", url = "/resources/manuals" }, - { name = "Tutorials", url = "/resources/tutorials" }, - { name = "FAQ", url = "/resources/faq" }, - # { name = "Blog", url = "/resources/blog" } - ] - [[languages.nl.menu.main]] - name = "Contacteer Ons" - url = "/contact" - weight = 5 + [[languages.nl.menu.main]] + name = "Functionaliteiten" + url = "/nl/features" + weight = 1 + [[languages.nl.menu.main]] + name = "Sectoren" + url = "/nl/sector" + weight = 2 + [languages.nl.menu.main.params] + has_submenu = true + submenu = [ + { name = "Grote lokale besturen", url = "/nl/sector/collectivities" }, + { name = "Diensten en verenigingen", url = "/nl/sector/associations" }, + ] + [[languages.nl.menu.main]] + name = "Tarieven" + url = "/nl/pricing" + weight = 3 + [[languages.nl.menu.main]] + name = "Hulpbronnen" + weight = 4 + [languages.nl.menu.main.params] + has_submenu = true + submenu = [ + # { name = "Blog", url = "/nl/resources/blog" }, + { name = "Handleidingen", url = "/nl/resources/manuals" }, + { name = "Tutorials", url = "/nl/resources/tutorials" }, + { name = "Installatie", url = "/nl/resources/installation" }, + { name = "Technische documentatie", url = "/nl/resources/technical-documentation" }, + { name = "FAQ", url = "/nl/resources/faq" } + ] + [[languages.nl.menu.main]] + name = "Contacteer ons" + url = "/nl/contact" + weight = 5 - [[languages.nl.menu.footer_column_1]] - name = "Download de CHILL-brochure" - url = "/pdf/Brochure_Chill.pdf" - weight = 1 + [[languages.nl.menu.footer_column]] + name = "Champs-Libres" + url = "https://www.champs-libres.coop/" + weight = 1 \ No newline at end of file diff --git a/themes/chill-theme/layouts/_default/baseof.html b/themes/chill-theme/layouts/_default/baseof.html index dc098d1..2fc1540 100644 --- a/themes/chill-theme/layouts/_default/baseof.html +++ b/themes/chill-theme/layouts/_default/baseof.html @@ -52,6 +52,19 @@ + + + {{ if hugo.IsMultilingual }} + {{ range .AllTranslations }} + + {{ end }} + {{ with hugo.Sites.Default.Home }} + + {{ end }} + {{ end }} + + + {{ partial "language-detection" . }} @@ -91,17 +104,6 @@ {{ partial "footer" . }} - - {{ if hugo.IsMultilingual }} - {{ if .Site.Params.visitorapi_pid }} - - {{ end }} - - {{ end }} - + {{ end }} + + {{ end }} + + + + + diff --git a/themes/chill-theme/layouts/partials/footer.html b/themes/chill-theme/layouts/partials/footer.html index c79ff18..edbcedc 100644 --- a/themes/chill-theme/layouts/partials/footer.html +++ b/themes/chill-theme/layouts/partials/footer.html @@ -130,10 +130,10 @@

- © {{ now.Format "2006" }} {{ .Site.Title }}. All rights reserved. + © {{ now.Format "2006" }} {{ with .Site.Title }}{{ . }}. {{ end }}{{ i18n "allRightsReserved" }}

- Designed by Champs-Libres + {{ i18n "designedBy" }} Champs-Libres
diff --git a/themes/chill-theme/layouts/partials/header.html b/themes/chill-theme/layouts/partials/header.html index bf871e6..93c84fd 100644 --- a/themes/chill-theme/layouts/partials/header.html +++ b/themes/chill-theme/layouts/partials/header.html @@ -89,21 +89,7 @@ {{ end }} - {{ if hugo.IsMultilingual }} -
-
{{ i18n "language" }}
- {{ range .Site.Languages }} - {{ if eq $.Site.Language.Lang .Lang }} - {{ .LanguageName }} - {{ else }} - {{ $langURL := printf "/%s/" .Lang }} - - {{ .LanguageName }} - - {{ end }} - {{ end }} -
- {{ end }} + {{ partial "language-switcher-mobile" . }} {{ if not $headerConfig.hideButtons }}
diff --git a/themes/chill-theme/layouts/partials/language-detection.html b/themes/chill-theme/layouts/partials/language-detection.html new file mode 100644 index 0000000..4d32b9d --- /dev/null +++ b/themes/chill-theme/layouts/partials/language-detection.html @@ -0,0 +1,106 @@ +{{/* + Language preference + browser language detection. + + Rendered inline in on purpose: it must run before the page paints so + a visitor is never shown a flash of the wrong language, and inlining avoids + an extra HTTP request for ~1 KB of script. + + Hugo hands the script everything it needs, so the script never has to guess + URLs: the home page of every language and the translations of *this* page. + That keeps it correct even though French is served from the site root ("/") + while the other languages sit under a prefix ("/en/", "/nl/"). +*/}} +{{ if hugo.IsMultilingual }} +{{ $homes := dict }} +{{ range hugo.Sites }} + {{ $homes = merge $homes (dict .Language.Lang .Home.RelPermalink) }} +{{ end }} +{{ $translations := dict }} +{{ range .AllTranslations }} + {{ $translations = merge $translations (dict .Lang .RelPermalink) }} +{{ end }} + +{{ end }} \ No newline at end of file diff --git a/themes/chill-theme/layouts/partials/language-switcher-mobile.html b/themes/chill-theme/layouts/partials/language-switcher-mobile.html new file mode 100644 index 0000000..b5e87a2 --- /dev/null +++ b/themes/chill-theme/layouts/partials/language-switcher-mobile.html @@ -0,0 +1,24 @@ +{{/* + Mobile language switcher, used inside the collapsed navigation menu. + Same translation-aware linking as the desktop switcher. +*/}} +{{ if hugo.IsMultilingual }} +{{ $page := . }} +
+
{{ i18n "language" }}
+ {{ range hugo.Sites }} + {{ $lang := .Language.Lang }} + {{ if eq $.Site.Language.Lang $lang }} + {{ .Language.LanguageName }} + {{ else }} + {{ $target := .Home }} + {{ range $page.AllTranslations }} + {{ if eq .Lang $lang }}{{ $target = . }}{{ end }} + {{ end }} + + {{ .Language.LanguageName }} + + {{ end }} + {{ end }} +
+{{ end }} \ No newline at end of file diff --git a/themes/chill-theme/layouts/partials/language-switcher.html b/themes/chill-theme/layouts/partials/language-switcher.html index 0041117..0747ded 100644 --- a/themes/chill-theme/layouts/partials/language-switcher.html +++ b/themes/chill-theme/layouts/partials/language-switcher.html @@ -1,8 +1,16 @@ +{{/* + Desktop language switcher. + + Links point at the translation of the *current* page when one exists, so + switching language keeps the visitor where they are. When the current page + has no translation we fall back to the home page of the target language. +*/}} {{ if hugo.IsMultilingual }} +{{ $page := . }} {{ $headerConfig := .Site.Params.header }} {{ $dropdownConfig := $headerConfig.menu.dropdown }}
-
-{{ end }} +{{ end }} \ No newline at end of file diff --git a/themes/chill-theme/layouts/partials/shortcodes/carousel.html b/themes/chill-theme/layouts/partials/shortcodes/carousel.html index 386427b..3a291e7 100644 --- a/themes/chill-theme/layouts/partials/shortcodes/carousel.html +++ b/themes/chill-theme/layouts/partials/shortcodes/carousel.html @@ -14,8 +14,8 @@ Author: Jeroen van der Schee {{ end }}
{{ if gt (len .images) 1 }} - - + +