Mis à jour à la fin du billet. Une deuxième fois.
Ces derniers jours, je me suis un peu cassé la tête avec la manière dont
hugo 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 :
<li>Publié le : {{ .date.Format "2006-01-02" }}</li>
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 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. 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 :
<li>Publié le : {{ dateFormat "2006-01-02" (default .Date (.PublishDate)) }}</li>
{{ if isset .Params "lastmod" }}
<li>Dernière mise à jour : {{ .Lastmod.Format "2006-01-02" }}</li>
{{ 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.
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)) }}
<li>Dernière mise à jour : {{ .Lastmod.Format "2006-01-02" }}</li>
{{ 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.