Franciser les dates dans Hugo

Un truc très agaçant avec Hugo, cet outil de génération de site statique écrit en go, c’est que tout est prévu pour avoir du contenu international (en plusieurs langues), sauf pour les dates. Hugo s’appuie sur des librairies de format de date du langage go, 100% américain, du coup c’est “allez-voir ailleurs si j’y suis” !

Merci les gars. En fait il y a plein d’autres pays dans le monde.

Le problème

Quand on regarde dans tous les templates pour afficher les dates dans un blog hugo, on trouve ceci :

{{ .Date.Format (.Site.Params.dateFormat | default "January 2, 2006" ) }}

Du coup, on se dit benoîtement : je change ce qu’il y a derrière default en mode “à la française” et ça va passer crème. Grave erreur :

{{ .Date.Format (.Site.Params.dateFormat | default "2 Janvier 2006" ) }}

Vous vous retrouverez avec toutes vos dates en Janvier, le jour et l’année seront bons, mais pas le mois.

Dans un échange dans un bug de 2015 (cf Issues #245: Date.Format Internationalization), la seule solution proposée est de ne pas utiliser janvier mais 01. C’est pas une réponse, puisque moi je veux afficher janvier et non january ou 01, mais le bug a été considéré comme fermé, bravo les gars 👏👏👏. Je vous poste ici un extrait :

Maybe I don’t understand well the logic of the .Date.Format variable, but it’s possible to change the language of the months (for example) when they are displayed?

Something like `{{ .Date.Format.IT “30 marzo 2006” }}

Remarquez que l’auteur, un italien, a fait la même démarche intellectuelle que moi, un français. La seule réponse a été (hors de “fais le en javascript”):

The standard Go time package don’t have internationalization built in. You can see the list of month names that Go is aware of here, and they’re all English. The easiest solution would probably be to display the months as numbers instead.

Vraiment choquant, rien n’existe hors des Etats-Unis pour les développeurs go. Les américains sont les seuls à utiliser les dates à l’envers en mode YYYY-DD-MM à la place du logique YYYY-MM-DD et le système impérial plutôt que le système métrique ISO…

Bref ! J’ai fini par trouver un échange sur le forum de Hugo à ce sujet avec un français qui pointait vers une solution qui fonctionne (et que j’ai choisi d’utiliser).

La solution

Je vous résume ici la solution de nicolinuxfr évoquée plus haut.

  • il vous faut un fichier data/mois.yaml pour faire le pont entre le numéro de mois et l’affichage en français
  • on va se servir du numéro de mois comme un index et stocker la valeur correspondante dans une variable locale : {{ $mymonths := index $.Site.Data.mois }} (je ne suis pas certain que cela soit nécessaire, mais pour le moment cela fonctionne bien pour moi)
  • avec printf on affiche cette valeur : {{ index $mymonths (printf "%d" .Date.Month) }} {{ .Date.Year }}

Ainsi, vos dates seront bien formattées en français, il faut mettre à jour toutes les parties du template qui affichent des dates (ne pas oublier de regarder dans les partials). Il me reste quelques explorations à faire :

  • est-ce que j’ai besoin de cette variable $mymonths ?
  • est-ce que je pourrais faire sauter la duplication (dans une partial) ? ça serait quand même plus propre et plus élégant.

Le code

Le fichier data/mois.yaml :

1: "janvier"
2: "février"
3: "mars"
4: "avril"
5: "mai"
6: "juin"
7: "juillet"
8: "août"
9: "septembre"
10: "octobre"
11: "novembre"
12: "décembre"

Le bout de code go pour remplacer les dates :

{{ $mymonths := index $.Site.Data.mois }}{{ .Date.Day }}
{{ index $mymonths (printf "%d" .Date.Month) }} {{ .Date.Year }}