--- title: "Les dates avec hugo" date: 2019-08-25T13:11:00+02:00 publishdate: 2019-08-26 draft: false categories: ["publication numérique"] tags: ["hugo", "dates", "configuration"] slug: les-dates-avec-hugo --- *[Mis à jour à la fin du billet](#mise-à-jour). [Une deuxième fois](#une-mise-à-jour-supplémentaire).* Ces derniers jours, je me suis un peu cassé la tête avec la manière dont [*hugo*](https://gohugo.io/) conçoit et traite les dates. Ce que je cherchais à réaliser ne me semblait pourtant pas si exotique. Lorsque l'on crée un nouveau contenu, par exemple un nouveau billet de blog, à l'aide de la commande `hugo new` (et en utilisant l'`archetype` par défaut), *hugo* ajoute dans les métadonnées (le *FrontMatter*) une valeur au champ date. Ce qui donne pour le fichier du texte que je rédige à l'instant : `date: 2019-08-25T13:11:00+02:00`. Dans le *template* qui permet d'afficher la date du billet de blog une fois le site généré, on peut trouver du HTML simplissime : ```
  • Publié le : {{ .date.Format "2006-01-02" }}
  • ``` Jusqu'ici, tout va bien. Pourtant, le plus souvent cette date ne correspond pas à la date effective de publication du billet, parce qu'entre le moment où je crée le fichier et le moment où il est suffisamment prêt pour être publié, il peut se passer plusieurs jours. Ça tombe bien, *hugo* propose une autre variable à ajouter, manuellement, dans les métadonnées, `publishdate`. Enfin, il peut également arriver qu'après la publication, il soit nécessaire de modifier un billet. Là aussi, il existe une variable, `lastmod`. Celle-ci peut-être ajoutée à la main ou renseignée par la date du dernier [*commit*](https://fr.wikipedia.org/wiki/Commit) de modification du fichier, si `enableGitInfo` est activé dans le fichier de configuration du site. Tout va bien dans le meilleur des mondes ? Presque. Assez logiquement, je trouve, je voulais afficher d'abord une date de publication, par exemple `date` ou `publishdate` si cette dernière date existe, et, le cas échéant, la date de la dernière modification. Ce faisant, j'ai été confronté à deux difficultés. La première était que toutes mes méthodes de tests logiques (si `publishdate` existe, alors affiche cette date, sinon affiche `date`, par exemple), provoquaient des erreurs lors de la génération du site. Pour avancer quand même, chaotiquement comme c'est mon habitude, j'ai fait abstraction des tests et tenter d'afficher toutes les dates. D'abord, j'ai été surpris de constater que si l'une d'elle n'existe pas, elle n'est simplement pas affichée. Il y a là un mécanisme qui m'échappe, mais pourquoi pas. L'autre point déroutant, est que les valeurs des dates affichées ne correspondaient pas à ce que j'avais imaginé. Souvent, `date` et `publishdate` étaient identiques, parfois `lastmod` également, parfois `lastmod` avait bien la valeur du dernier *commit* correspondant à la dernière modification du billet concerné~~, mais pas lorsqu'il s'agissait du premier *commit*~~. J'ai essayé de nombreuses choses, tenté de comprendre la documentation de *hugo*, fouillé dans les forums… de m'arracher mes cheveux, de jurer et d'insulter le Web, en vain. Avant de tomber sur une discussion sur le forum de *hugo* dans laquelle était signalée la section suivante de la documentation : [*Configure dates*](https://gohugo.io/getting-started/configuration/#configure-dates). Je l'ai lue attentivement et j'ai fini par comprendre ce qui se passait, à défaut de tout à fait comprendre la logique à l'œuvre. Pour obtenir un comportement qui correspond à ce que je voudrais, il faut que dans le fichier de configuration de mon site (`config.toml`), je redéfinisse à ma guise la manière dont les variables de dates sont renseignées. ``` [frontmatter] date = ["date", "publishDate"] lastmod = [":git", "lastmod"] ``` Avec cette méthode, j'évite que le champ `date` puisse récupérer la valeur de `lastmod` et que celui-ci puisse obtenir la valeur de `date` ou `publishdate`. Du coup, je peux les distinguer, pour avoir une date de publication et/ou une date de dernière mise à jour. Si la date de publication est différente de la date de création du fichier, je dois manuellement, soit modifier la valeur de `date` dans le *FrontMatter*, soit y ajouter la variable `publishdate`. `lastmod` par contre, peut-être inférée de l'historique `git`, pour autant que `enableGitInfo` soit bien à `true` dans la configuration. Au niveau des *template*, ça peut donner ceci : ```
  • Publié le : {{ dateFormat "2006-01-02" (default .Date (.PublishDate)) }}
  • {{ if isset .Params "lastmod" }}
  • Dernière mise à jour : {{ .Lastmod.Format "2006-01-02" }}
  • {{ end }} ``` Il n'est pas du tout invraisemblable que cette solution puisse être améliorée. Ce que je retiens de cette aventure, c'est que *hugo* est décidément très puissant, le résultat d'une réflexion plutôt poussée et que j'ai encore beaucoup de travail avant d'arriver à un niveau suffisant de compréhension de son fonctionnement. ## Mise à jour Visiblement la logique ci-dessus est incomplète (et risque bien de l'être après cette mise à jour, mais c'est ainsi). Sur ce même billet, lors de la publication, enfin un peu après, j'ai constaté que la date de modification était plus récente que la date de publication, ce qui est logique, parce que la date du commit est plus ancienne que `publishdate`, contrairement à ce que je prétends plus haut. {{< figure src="/images/wrong-dates.png" caption="Première publication, avec la mauvaise date" >}} Aussi, j'ai rajouté un test dans le *template* : ``` {{ if (and (isset .Params "lastmod") (gt .Lastmod .PublishDate)) }} ``` D'abord, on vérifie que la variable `lastmod` est bien renseignée, puis que sa date est plus récente que `publishdate`, avant de l'afficher. Voilà, j'espère que désormais je vais obtenir le comportement que je souhaite. ## Une mise à jour supplémentaire > « Voilà, j'espère que désormais je vais obtenir le comportement que je > souhaite. » Hé bien non. Souvent, la `lastmod` est affichée, alors qu'elle est du même jour que la `publishdate`, et en fait, c'est logique. Il se trouve que je renseigne la `publishdate` manuellement, parce que je veux qu'elle soit différente de la date de création du fichier (le résultat de la commande `hugo new`) et qu'elle ne soit pas modifiée par les dates des commits qui viendraient après, puisque ces modifications sont des mises à jour, pas un changement de la date de publication. Or, je ne m'amuse pas à créer une date de publication à la seconde près, une date du type `2020-05-22` me suffit. Par contre, pour la `lastmod`, la date vient de `git`, et là c'est précis, à la seconde près. Ce qui a pour conséquence qu'une comparaison d'une date de publication et et la date du dernier commit qui tombent le même jour, donnera toujours la `lastmod` comme plus grande que la `publishdate`. Mon gabarit va dont l'afficher. La solution, évidente pour des gens dont c'est le métier, j'imagine, est de traiter ces dates pour pouvoir les comparer de manière sensée : ``` {{ $LastmodFormatted := dateFormat "2006-01-02" (.Lastmod) }} {{ $PublishdateFormatted := dateFormat "2006-01-02" (.PublishDate) }} ``` On compare ces dates formatées et on affiche la dernière modification si elle est plus récente que le jour de publication : ``` {{ if (and (isset .Params "lastmod") (gt $LastmodFormatted $PublishdateFormatted)) }}
  • Dernière mise à jour : {{ .Lastmod.Format "2006-01-02" }}
  • {{ end }} ``` Et si on fait des mises à jour le même jour, ça ne sera pas affiché, mais peut-être bien que c'est sensé, au fond.