Ajouter le support multilingue Ă son blog GitHub
Mis Ă jour le 28/07/2026 !
Cet article a été rédigé sous le framework Jekyll. Il a depuis migré vers Astro !
Mis Ă jour le 15/09/2024 !
CâĂ©tait bien dâoffrir un support multilingue, mais la maintenance est devenue trop difficile et complexe, jâai donc annulĂ© lâapplication du plugin et suis revenu Ă lâĂ©tat antĂ©rieur. Pour un vrai support multilingue, il faut retoucher bien plus dâĂ©lĂ©ments quâon ne le pense, ce qui rend le processus de fusion avec le thĂšme dâorigine trĂšs complexe â un inconvĂ©nient Ă accepter.
Présentation du plugin
Il existe principalement deux plugins Jekyll pour implĂ©menter le multilingue dans lâenvironnement GitHub Blog : jekyll-polyglot et jekyll-multiple-languages-plugin. Jâai utilisĂ© le premier, jekyll-polyglot. Ce plugin gĂ©nĂšre des pages de traduction multilingue en insĂ©rant le code de langue I18N aprĂšs lâURL racine, selon la valeur lang dĂ©finie dans le front matter de chaque article. Ce plugin aurait Ă©tĂ© créé sur le modĂšle du second, jekyll-multiple-languages-plugin. Le guide officiel, de lâinstallation aux prĂ©cautions dâutilisation, est dĂ©taillĂ© sur le dĂ©pĂŽt GitHub Polyglot.
Travail préparatoire
Installation et configuration du plugin
group :jekyll_plugins do
gem "jekyll-polyglot"
end
Ajoutez le plugin comme ci-dessus dans Gemfile, puis installez-le avec la commande gem install jekyll-polyglot.
plugins:
- jekyll-polyglot
languages: ["ko", "en"]
default_lang: "ko"
exclude_from_localization: ['javascript', 'images', 'css', 'sitemap.xml']
parallel_localizaion: true
Une fois le plugin installĂ©, ajoutez ces Ă©lĂ©ments Ă _config.yml. Dans languages, indiquez les langues que la page supportera, et dans default_lang, la langue par dĂ©faut de la page. Attention : sous Windows, lâoption parallel_localization ne fonctionne pas correctement, il faut donc impĂ©rativement la dĂ©finir sur false.
Correction dâun bug dâexpression rĂ©guliĂšre
AprĂšs avoir installĂ© le plugin et effectuĂ© une compilation, on rencontre lâerreur : 'relative_url_regex': target of repeat operator is not specified:. Cette erreur se produit parce que certaines expressions rĂ©guliĂšres du fichier site.rb du plugin ne gĂšrent pas les caractĂšres gĂ©nĂ©riques (*) comme exlude: *.gem *.gemspec *.config.js dans le _config.yml du thĂšme Chirpy. Jâai contactĂ© lâauteur du plugin Ă ce sujet, mais on mâa rĂ©pondu, en se rĂ©fĂ©rant Ă cette documentation, que le thĂšme Chirpy utilisait incorrectement les motifs globaux dans _config.yml.
Cependant, dâautres thĂšmes Jekyll comme Minimal-Mistakes utilisent Ă©galement des motifs globaux, ce qui suggĂšre quâil faut modifier le code du plugin lui-mĂȘme. Jâai donc forkĂ© le projet dans mon dĂ©pĂŽt GitHub et lâai chargĂ© dans Gemfile comme suit :
gem 'jekyll-polyglot', git: 'https://github.com/hyngng/jekyll-polyglot', branch: 'master'
Ensuite, jâai modifiĂ© les deux fonctions relative_url_regex() et absolute_url_regex() dans le fichier site.rb situĂ© dans jekyll-polyglot-1.8.0/lib/jekyll/polyglot/patches/jekyll, comme ci-dessous :
def relative_url_regex(disabled = false)
regex = ''
unless disabled
@exclude.each do |x|
escaped_x = Regexp.escape(x)
regex += "(?!#{escaped_x})"
end
@languages.each do |x|
escaped_x = Regexp.escape(x)
regex += "(?!#{escaped_x}\/)"
end
end
start = disabled ? 'ferh' : 'href'
%r{#{start}="?#{@baseurl}/((?:#{regex}[^,'"\s/?.]+\.?)*(?:/[^\]\[)("'\s]*)?)"}
end
...
def absolute_url_regex(url, disabled = false)
regex = ''
unless disabled
@exclude.each do |x|
escaped_x = Regexp.escape(x)
regex += "(?!#{escaped_x})"
end
@languages.each do |x|
escaped_x = Regexp.escape(x)
regex += "(?!#{escaped_x}\/)"
end
end
start = disabled ? 'ferh' : 'href'
%r{(?<!hreflang="#{@default_lang}" )#{start}="?#{url}#{@baseurl}/((?:#{regex}[^,'"\s/?.]+\.?)*(?:/[^\]\[)("'\s]*)?)"}
end
AprĂšs avoir modifiĂ© les fonctions, jâai entrĂ© la commande bundle exec jekyll s et confirmĂ© que la compilation sâeffectuait sans problĂšme.
Modification des attributs des fichiers dâarticles
---
lang: en
permalink: example-url-here
---
Il faut spĂ©cifier la valeur de la langue dans le front matter des articles Ă traduire. Utilisez les codes de pays I18N comme ko, en. Dans mon cas, jâai utilisĂ© ko-KR et en. Le champ permalink dĂ©termine le chemin URL de lâarticle, car dans Jekyll, deux fichiers ayant la mĂȘme URL sont considĂ©rĂ©s comme identiques par dĂ©faut, il faut donc distinguer artificiellement lâoriginal de la traduction.
_posts/2010-03-01-salad-recipes-en.md
_posts/2010-03-01-salad-recipes-sv.md
_posts/2010-03-01-salad-recipes-fr.md
Si vous nâaimez pas distinguer la langue de lâarticle via permalink dans le front matter, vous pouvez Ă©galement modifier le nom du fichier comme ci-dessus. Cependant, dans ce cas, lâURL de la page pourrait contenir une rĂ©pĂ©tition, comme example.github.io/en/2010-03-01-salad-recipes-en.
Modification du template
Ces informations Ă©tant spĂ©cifiques au thĂšme Chirpy, si vous utilisez un autre template Jekyll, vous pouvez passer cette section et passer directement Ă la section suivante. Cependant, si vous devez modifier le template Chirpy comme moi, les informations suivantes peuvent vous ĂȘtre utiles.
- Variables utilisables dans le plugin jekyll-polyglot :
site.default_lang: la langue par dĂ©faut dĂ©clarĂ©e dans_config.yml.site.active_lang: la langue activĂ©e sur la page web actuelle.page.lang: la langue de lâarticle dĂ©clarĂ©e dans le front matter.
En utilisant ces trois variables, on peut par exemple Ă©crire des conditions comme {% raw %}{% if page.lang == site.default_lang %}{% endraw %}, et limiter lâaffichage de la langue sur la page en fonction du contexte.
Chargement de la langue du site
{% if site.active_lang %}
{% assign lang = site.active_lang %}
{% elsif site.data.locales[page.lang] %}
{% assign lang = page.lang %}
{% elsif site.data.locales[site.lang] %}
{% assign lang = site.lang %}
{% else %}
{% assign lang = 'site.default_lang'' %}
{% endif %}
Le template Chirpy dĂ©finit la langue dans un fichier sĂ©parĂ©, _includes/lang.html. AprĂšs avoir modifiĂ© ce fichier comme ci-dessus, on peut lâutiliser en important lang.html dans les fichiers de mise en page dĂ©taillĂ©s.
Affichage du contenu par langue
{% include lang.html %}
La plupart du temps, jâai traitĂ© les choses en important lang.html comme ci-dessus. Pour la pagination et dâautres cas, simplement changer la langue dĂ©signĂ©e ne suffisait pas, jâai donc créé des formules supplĂ©mentaires. La plupart du temps, jâai modifiĂ© les pages pour quâelles nâaffichent que les informations liĂ©es aux articles rĂ©digĂ©s dans la langue spĂ©cifique.
<div id="post-list" class="flex-grow-1 px-xl-1">
{% for post in posts %}
{% if post.lang == site.active_lang %}
<article class="card-wrapper card">...</article>
{% endif %}
{% endfor %}
</div>
Par exemple, jâai ajoutĂ© la condition {% raw %}{% if post.lang == site.active_lang %}{% endraw %} dans _layouts/home.html pour que la page dâaccueil nâaffiche que les articles rĂ©digĂ©s dans la langue active du site. Voici les autres fichiers que jâai modifiĂ©s en dĂ©tail :
| Usage | Chemin du fichier |
|---|---|
| ModĂšle de cadre commun | _layouts/default.html |
| Page dâaccueil | _layouts/home.html |
| Catégories | _layouts/category.html |
| Page de tags | _layouts/tags.html |
| Page dâarchives | _layouts/archive.html |
| Page Ă propos | _layouts/about.html |
| Articles récemment modifiés | _includes/update-list.html |
| Exploration de tags | _includes/trending_tags.html |
| Articles connexes | _includes/related-posts.html |
| Navigation entre articles | _includes/post-nav.html |
| Pagination | _includes/post-paginator.html |
Distinction du contenu de la page Ă propos
{% if site.active_lang == 'ko-KR' %}
## ìêž°ìê° (corĂ©en)
...
{% elsif site.active_lang == 'en' %}
## English Self-Introduction
...
{% endif %}
Voici comment afficher un contenu diffĂ©rent dans la page Ă propos (about) selon la langue. Au dĂ©but, je pensais devoir crĂ©er des fichiers sĂ©parĂ©s comme about-en.md, mais il sâest avĂ©rĂ© que la mĂ©thode la plus simple Ă©tait dâafficher un contenu diffĂ©rent dans un seul fichier en fonction de la langue du site.
Affichage naturel du nombre de caractĂšres
<span
class="readtime"
data-bs-toggle="tooltip"
data-bs-placement="bottom"
title="{{ words }}{% if site.active_lang != 'ko-KR' %}{{ ' ' }}{% endif %}{{ site.data.locales[include.lang].post.words }}
>
Un petit dĂ©tail qui me gĂȘnait. Dans ce thĂšme, lorsquâon survole le temps de lecture en haut de lâarticle, le nombre de caractĂšres sâaffiche, mais indĂ©pendamment de la langue, il y a un espace entre le nombre et lâunitĂ©, ce qui donne « 1000 ì ». Je trouvais cela peu naturel, jâai donc modifiĂ© lâaffichage : en corĂ©en, cela sâaffiche comme « 1000ì », et dans les autres langues, avec un espace, comme « 1000 words ».
Autres travaux
Indication de la langue de la page dans lâen-tĂȘte
{% I18n_Headers %}
Câest une recommandation du Guide international et multilingue du Centre de recherche Google. Ce nâest pas obligatoire, mais si vous ĂȘtes soucieux du SEO, il est bon dâajouter le code ci-dessus dans lâen-tĂȘte pour indiquer la langue de la page. Le code se transforme comme suit aprĂšs compilation :
<meta http-equiv="Content-Language" content="ko-KR">
<link rel="alternate" hreflang="ko-KR" href="ttps://hyngng.github.io/posts/:title/"/>
<link rel="alternate" hreflang="en" href="https://hyngng.github.io/en/posts/:title/"/>
Inclusion du plugin dans le processus de compilation
name: Jekyll site CI
on:
push:
branches: [ "site" ]
pull_request:
branches: [ "site" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the site in the jekyll/builder container
run: |
docker run \
-v $:/srv/jekyll -v $/_site:/srv/jekyll/_site \
jekyll/builder:latest /bin/bash -c "chmod -R 777 /srv/jekyll && jekyll build --future"
- name: Push
uses: s0/git-publish-subdir-action@develop
env:
REPO: self
BRANCH: main
FOLDER: _site
GITHUB_TOKEN: $
MESSAGE: "Build: ({sha}) {msg}"
Contrairement aux plugins intĂ©grĂ©s par dĂ©faut, jekyll-polyglot est considĂ©rĂ© comme un plugin externe et doit ĂȘtre compilĂ© sĂ©parĂ©ment pour des raisons de sĂ©curitĂ©. CrĂ©ez un nouveau fichier .yml dans le dossier .github/workflows/ et Ă©crivez-le comme ci-dessus pour une compilation sans problĂšme.
Inclusion de toutes les pages dans le sitemap
...
{% for lang in site.languages %}
{% for post in site.posts %}
{% if lang == post.lang %}
<url>
<loc>
{{ site.url }}
{% if lang == site.default_lang %}
{{ post.url }}
{% else %}
{{ post.url | prepend: lang | prepend: '/' }}
{% endif %}
</loc>
...
</url>
{% endif %}
{% endfor %}
{% endfor %}
Le sitemap est lâun des plus grands problĂšmes du support multilingue, car il ne gĂ©nĂšre les balises <loc> que pour les pages par dĂ©faut. Au lieu de cela, jâai modifiĂ© le code pour quâil vĂ©rifie chaque langue dans site.languages, tout en ignorant les Ă©lĂ©ments non valides, comme les pages corĂ©ennes automatiquement gĂ©nĂ©rĂ©es Ă partir dâun fichier dĂ©fini avec lang: en.
Ajout dâun bouton de changement de langue sur la page
{% for lang in site.languages %}
<div class="lang" style="display: inline;">
<a style="
{% if lang == site.active_lang %}
font-weight: bold;
{% endif %}"
href="
{% if lang == site.default_lang %}
{{site.baseurl}}{{page.url}}
{% else %}
{{site.baseurl}}/{{ lang }}{{page.url}}
{% endif %}">
{{ lang }}
</a>
{% if forloop.last == false %}
<span class="lang-border"> </span>
{% endif %}
</div>
{% endfor %}
Si nĂ©cessaire, on peut ajouter un bouton de changement de langue Ă lâendroit souhaitĂ© avec le code ci-dessus. Personnellement, comme mon blog ne contient pas vraiment de contenu exclusif par langue, et que les visiteurs nâont pas nĂ©cessairement besoin de voir la page dans une autre langue, je ne lâai pas ajoutĂ©.
Distinction du contenu du flux par langue
{% assign filtered_posts = site.posts | where: "lang", site.active_lang %}
{% for post in filtered_posts limit: 5 %}
<entry> ... </entry>
{% endfor %}
Jâai Ă©galement fait en sorte que le flux ne contienne que les articles correspondant Ă site.active_lang dans filtered_posts, gĂ©nĂ©rĂ© dynamiquement selon la configuration linguistique. Lors de lâinscription aux outils pour webmasters, jâai enregistrĂ© feed.xml et /en/feed.xml sĂ©parĂ©ment.
Capture dâĂ©cran de lâapplication


Conclusion
CâĂ©tait Ă©prouvant. jekyll-polyglot donne plus lâimpression dâĂȘtre encombrant que flexible et pratique. Le processus dâapplication nâest vraiment pas facile ni agrĂ©able â câest le moins quâon puisse dire. Jâai mĂȘme envisagĂ© de crĂ©er une page sĂ©parĂ©e en anglais et de gĂ©rer les deux versions indĂ©pendamment, mais comme cela prĂ©sentait plus dâinconvĂ©nients (synchronisation du contenu, configuration de lâexposition dans les moteurs de recherche, etc.), jâai choisi dâutiliser jekyll-polyglot. Cependant, une fois lâimplĂ©mentation rĂ©ussie, les avantages quâapporte jekyll-polyglot pour crĂ©er un systĂšme multilingue maison sont indĂ©niables.