Description
Un shortcode Hugo est un fichier contenant un type précis d’éléments HTML (HyperText Markup Language) pour pouvoir augmenter les possibilités d’Hugo.
Lors d’un appel de ce shortcode depuis un fichier MD (MarkDown) , un traitement est fait afin de remplacer l’appel du shorcode par le traitement restitué par le shortcode lui-même.
Il est ainsi possible par ce biais d’appeler des iframes, des figures, etc… voire un fichier MD lui-même.
Les shortcodes s’enregistrent dans le répertoire layout/shortcodes/.
Documentation
- l’officielle, en anglais : Hugo Documentation : Content management > Shortcodes
Mes shortcodes
Mes usages pour l’instant sont très basiques ; en soit ce que je fais au-travers de plusieurs pourraient être directement écrit dans le fichier MD au format HTML , et zou, basta…
Néanmoins, il faut avouer que pour l’inclusion d’exemples de code, surtout dans un site multilangue est franchement utile.
abbreviations
Ce shortcode a deux versions légérement différentes.
J’ai commencé historiquement avec la version v1 puis au cours d’une
refonte en novembre 2025, j’ai écrit une v2 qui a pour avantage lors
du premier appel concernant un sigle/une abbréviation d’écrire la définition à
côté de celui-ci, puis pour les appels suivants s’ils existent dans la page
en cours, de les afficher sous forme d’abbréviations
HTML
.
abbr-v1
Gestion des abbréviations, élément
HTML
abbr :
Source brute vers le shortcode : abbr
<abbr {{ .Get 1 | printf `title=%q` | safeHTMLAttr }}>{{ .Get 0 | safeHTML }}</abbr>
L’appel du shortcode est simple :
Code : shortcode
{{< abbr accronym "Meaning of Acronym" >}}
accronymest l’acronyme ou l’abbréviationMeaning of Acronymest la signification de l’acronyme
Exemple : HTML est écrit ainsi :
Code : shortcode
{{< abbr HTML "HyperText Markup Language" >}}
abbr-v2
Tout commence par l’ajout du fichier tiers dans le répertoire data, nommé
terms.yaml.
Chaque terme a au minimum deux entrées :
- la première nommée
abbrqui prend le nom du sigle - la seconde nommée
termqui est la définition du sigle
Ainsi par exemple, le fichier data/terms.yaml comprendra pour la définition
du terme CSS, l’entrée suivante :
- abbr: CSS
term: Cascade Style Sheet
Ensuite le shortcode appelé est - un poil plus compliqué que la v1 - :
Source brute vers le shortcode : abbr2
{{/* variables based on shortcode argument */}}
{{- $entry := ( .Get 0 | safeHTML ) -}}
{{- $count_id := print $entry "_count" -}}
{{/* range over data file */}}
{{- range site.Data.terms }}
{{/* Find matches */}}
{{- if eq ( .abbr ) $entry }}
{{- if gt ( $.Page.Scratch.Get ( $count_id )) 0 }}
<abbr title="{{- .term -}}">{{- .abbr -}}</abbr>
{{- else -}}
<span>{{- .abbr }} <em>({{ .term -}})</em></span>
{{- $.Page.Scratch.Set ( $count_id ) 1 -}}
{{- end -}}
{{- end -}}
{{- end -}}
Exemple : HTML est écrit ainsi :
Code : shortcode
{{< abbr2 HTML >}}
C’est ce qui se passe sur cette page en cours, pour exemple remarquez dès le début de page ce qu’il en est de l’accronyme HTML , puis les récurrences suivantes.
anchor
La gestion des ancres dans une même page est un peu plus délicate :
Source brute vers le shortcode : anchor
{{ $txt := .Get 0 | safeHTML }}{{ $name := .Get 1 | lower | safeHTML }}{{ $anchor := anchorize $name }}
<a href="{{ printf "%s" .Page.RelPermalink }}#{{ $anchor }}" title="{{ i18n "shortcodeAnchorTitle" }}{{ $name }}">{{ $txt }}</a>
L’appel du shortcode :
Code : shortcode
{{< anchor "Texte" "Cible" >}}
Exemple : Ce lien renvoie au chapitre Description, et est écrit ainsi :
Code : shortcode
{{< anchor "lien" "description" >}}
blockquote
Ahhh, la gestion des citations, autrement dit des éléments blockquote
m’en a fait baver. :p
En même temps, j’ai voulu pour des histoires d’esthétiques CSS (Cascade Style Sheet) les “améliorer”.
Basiquement, il suffit :
<blockquote>
{{ $file := .Get 0 | readFile | htmlUnescape | safeHTML }}{{ $file }}
</blockquote>
Mon shortcode est un poil plus évolué, car le site étant multilangue, il appele le shortcode interne dédiée à la gestion multilange, le reste n’étant que de la mise en forme CSS :
Source brute vers le shortcode : blockquote
<div class="info-quote">
<p class="text-white-50">
{{ T "quoteTitle" }}{{ if .Get 1 }} <em>{{ .Get 1 | safeHTML }}</em>{{ end }}
</p>
</div>
<div class="quote">
<blockquote>
{{ $name := .Get 0 }}{{ $file := urlize (print "/content/inc/" $name) | readFile | htmlUnescape | safeHTML }}{{ $file }}
</blockquote>
</div>
L’appel du shortcode est :
Code : shortcode
{{< blockquote "blockquote-filename" lang >}}
blockquote-filenameest le nom du fichier à appeler contenant la citation à montrer.langest le nom de la langue cible, telen,fr, etc…- Pour ne préciser aucun langage en soit, utilisez
"" - deux fois les double quotes -.
- Pour ne préciser aucun langage en soit, utilisez
Exemple :
Code : shortcode
{{< blockquote "web-hugo-shortcode-example-blockquote" fr >}}
Restitue :
Citation : fr
Code
L’inclusion de code !
Pour pouvoir utiliser cette fonction, j’ai créé à la racine du répertoire
content/ un sous répertoire nommé inc - vous pouvez très bien
l’appeler autrement, à vous d’adapter lors de l’appel du shortcode - ;
puis je créé mes fichiers à inclure dans ce répertoire.
Encore une fois, de manière basique, il suffit de :
Code : html
{{ $file := .Get 0 | readFile }}{{ $lang := .Get 1 }}{{ $opt := "" }}<div class="code">{{ highlight $file $lang $opt }}</div>
Mon shortcode, un poil plus évolué , du fait d’être multilangue :
Source brute vers le shortcode : code
{{ $name := .Get 0 }}{{ $file := urlize (print "/content/inc/" $name) | readFile }}{{ $lang := .Get 1 }}{{ $opt := "" }}
<div class="info-code"><p class="text-white-50">{{ i18n "codeTitle" }} <em>{{ $lang }}</em></p></div><div class="code">{{ highlight $file $lang $opt }}</div>
L’appel du shortcode :
Code : shortcode
{{< code "code-filename" language >}}
code-filenameest le nom du fichier à appeler contenant le code à montrer.languageest le nom du langage cible, telsh,PHP,python, etc…- Pour ne préciser aucun langage en soit, utilisez
"" - deux fois les double quotes -.
- Pour ne préciser aucun langage en soit, utilisez
Exemple : Regardez bien, vous en avez un, juste au-dessus… lors de l’appel du premier shortcode concernant ce shortcode !
Color
Un tout petit shortcode pour gérer un bout de texte en couleur…
Néanmoins, pour cela, j’ai défini dans ma feuille de style, des types de
couleurs nommées.
Source brute vers le shortcode : color
<span {{ .Get 0 | printf `class=%q` | safeHTMLAttr }}>{{ .Inner }}</span>
L’appel du shortcode est simple :
Code : shortcode
{{< color "css-name" >}}text{{< /color >}}
css-nameest le nom de la déclaration CSStextest le texte à coloriser
Exemple : Ceci est un texte vert , celui qui suit est orangé , cet autre est rouge , etc…
File
L’inclusion d’un exemple de fichier est un dérivé du shortcode code, mais au lieu de produire un bloc de code précédé d’un entête présentant le code, j’appelle un entête qui restitue le nom de fichier tel que désiré.
Donc, basiquement c’est le même shortcode que pour code.
De manière plus évolué, cela donne ainsi :
Source brute vers le shortcode : file
{{ $name := .Get 0 | safeHTML }}{{ $file := urlize (print "/content/inc/" $name) | readFile }}{{ $lang := .Get 1}}{{ $filename := .Get 2 }}{{ $opt := "linenos=table" }}
<div class="info-file"><p class="text-white-50">{{ i18n "fileTitle" }}<em>{{ $filename }}</em></p></div><div class="code">{{ highlight $file $lang $opt }}</div>
L’appel du shortcode :
Code : shortcode
{{< file "example-file" language "filename" >}}
/example-fileest le nom du fichier à appeler contenant le contenu d’un fichier à montrer.languageest le nom du langage cible, telsh,PHP,python, etc…- Pour ne préciser aucun langage en soit, utilisez
"" - deux fois les double quotes -.
- Pour ne préciser aucun langage en soit, utilisez
filenameest le nom du fichier - celui qui est affiché.
Exemple : y’a-t-il vraiment besoin encore de le prouver ? Regardez bien juste au-dessus ;)
Image
Il est vrai que
MD
a un code prévu pour l’inclusion d’image, mais
j’ai crée ce shortcode pour pouvoir spécifier une taille d’image et
renvoyé vers l’image source par le biais d’un élément
HTML
a
appliqué sur l’élément
HTML
img.
PNG/JPG/Tiff
Prenons en considération que les images sont fournies en tant qu’assets :
Source brute vers le shortcode : img
1{{/* runner for assets/image */}}
2{{- $src := resources.Get (printf "%s%s" "/images/" (.Get "s")) -}}{{- $alt := .Get "a" | safeHTML -}}{{- $width := printf "%s" (.Get "w") -}}
3{{- $img := $src -}}
4{{- with $width -}}{{- $img = $src.Resize (printf "%sx" $width) -}}{{- end -}}
5{{- with $img -}}
6<figure>
7 <a href="{{ $src.RelPermalink }}" title="{{ $alt }}">
8 <picture>
9 <!-- <source srcset="/img/.avif" type="image/avif"> -->
10 {{- with .Resize (printf "%dx%d webp" .Width .Height) }}
11 <source srcset="{{ .RelPermalink }}" type="image/webp">
12 {{ end }}
13 <img alt="{{ $alt }}" loading="lazy" src="{{ .RelPermalink }}" type="{{ .MediaType }}" height="{{ .Height }}" width="{{ .Width }}">
14 </picture>
15 </a>
16 <figcaption>{{ $alt }}</figcaption>
17</figure>
18{{- end -}}
L’appel du shortcode :
Code : shortcode
{{< img a="alt" s="src" w="width" >}}
Les paramètres nommés sont :
a: l’équivalent de l’attributalts: l’équivalent de l’attributsrcw: l’équivalent de l’attributwidth
Exemple :
Cette image représentant mon logo, ayant pour titre “Mon Logo”, a une taille de 192 px (pixels) , redimensionnée à la taille de 124 pixels, et est au format PNG (Portable Network Graphics) .
SVG
Concernant les images au format SVG (Scalable Vector Graphics) , je les gère différemment du précédent shortcode :
Source brute vers le shortcode : figure-svg
1{{/* runner for assets/svg */}}
2{{- $class := .Get "class" -}}{{- $src := resources.Get (printf "%s%s" "/svg/" (.Get "src")) -}}{{ $title := .Get "title" }}
3{{ with $src }}
4<figure class="{{ if $class }}{{ $class }}{{ end }}">
5 <a href="{{ .RelPermalink }}" title="{{ $title }}">
6 {{ .Content | safeHTML }}
7 </a>
8 {{ if $title }}<figcaption aria-hidden="true" class="hidden" hidden>{{ $title }}</figcaption>{{ end }}
9</figure>
10{{ end }}
L’appel du shortcode :
Code : shortcode
{{< figure-svg class="class-name" src="image.svg" title="the title" >}}
Exemple :
kbd
Ce shortcode est utilisé pour la gestion de l’élément
HTML
kbd.
Source brute vers le shortcode : kbd
{{ $k := .Get 0 | safeHTML }}<kbd>{{ $k }}</kbd>
L’appel du shorcode :
Code : shortcode
{{< kbd key >}}
keyest le nom de la touche clavier !
Exemple : voici le rendu de la touche A !
Lien interne
Ce shortcode a deux versions légérement différentes. J’ai commencé avec la première, puis un jour, je me suis demandé comment faire pour “injecter” aussi le nom d’une ancre ; la v2 est née !
Inside v1
Pour gérer les liens internes entre les pages de ce site, je me suis évertué à mettre en place le shortcode suivant :
Source brute vers le shortcode : inside
1{{ $link := .Get 0 }}{{ $link := replace $link ":" "/" }}{{ $url := (print ( relLangURL $link ) "/") }}
2{{ if .Get 1 }}{{ $txt := .Get 1 }}
3<a class="inside" href="{{ $url }}" title="{{ i18n "lnkInsideTitle" }}{{ with .Site.GetPage $link }}{{ .Title }}{{ end }}">{{ $txt }}</a>
4{{ else }}
5{{ with .Site.GetPage $link }}{{ $title := .Title }}<a class="inside" href="{{ $url }}" title="{{ i18n "lnkInsideTitle" }}{{ $title }}">{{ $title }}</a>{{ end }}
6{{ end }}
De même, j’ai créé une définition
CSS
, nommée inside, qui me
permet de modifier légérement le rendu pour les liens internes.
L’appel du shortcode :
Code : shortcode
{{< inside "section:subsection:pagename" "Title" >}}
- les noms de sections et pages sont séparés par un
: - Le titre peut être omis, dans ce cas-là sera affiché celui de la page appelée.
Exemples :
- Là, j’appelle la page Hugo : Déploiement SFTP et c’est son titre qui est fourni, ainsi que l’ URL (Uniform Resource Locator) adéquate
- Dans cet exemple, je force le titre dans l’appel de ma page Déploiement d'un site statique par Hugo
Inside v2
Cette version est subtilement différente :
Source brute vers le shortcode : inside2
1{{ $link := .Get "l" }}{{ $link := replace $link ":" "/" }}{{ $url := (print ( relLangURL $link ) "/") }}{{ $anchor := .Get "a" }}
2{{ if .Get "t" }}{{ $txt := .Get "t" }}<a class="inside" href="{{ $url }}{{ if $anchor }}#{{ $anchor }}{{ end }}" title="{{ i18n "lnkInsideTitle" }}'{{ with .Site.GetPage $link }}{{ .Title }}{{ end }}'">{{ $txt }}</a>
3{{ else }}
4{{ with .Site.GetPage $link }}{{ $title := .Title }}<a class="inside" href="{{ $url }}{{ if $anchor }}#{{ $anchor }}{{ end }}" title="{{ i18n "lnkInsideTitle" }}'{{ $title }}'">{{ $title }}</a>{{ end }}
5{{ end }}
L’appel du shortcode :
Code : shortcode
{{< inside2 l="section:subsection:pagename" t="title" a="anchor-name" >}}
Les paramètres nommés sont :
a: cible une ancre dans le document appelé ; bien-sûr, cette ancre doit exister… dans le document en question. Peut-être omise !l: nom du lien interne ; les noms de sections et pages sont séparés par le symbole:t: le titre. Peut être omis, dans ce cas-là sera affiché celui de la page appelée.
Exemple :
- Là, j’appelle la page Hugo : Déploiement SFTP ; c’est son titre qui est fourni, ainsi que l’ URL adéquate, mais elle pointe vers le chapitre rsync, ciblée par l’ancre correspondante.
- Dans cet exemple, je force le titre dans l’appel de ma page Déploiement d'un site statique par Hugo mais je ne cible pas d’ancre.
Note
Les blocs d’alertes ou de notes sont des blocs de code HTML présentant un texte et mis en valeur selon un identifiant, qui est traduit selon la langue utilisée.
La valeur de cet identifiant peut être :
dangerpour afficher une alerte de type ‘danger’ qui aura une teinte rougéeinfopour afficher un message de type ‘information’ qui aura une teinte bleutéesuccesspour afficher un message de type ‘succès’ qui aura une teinte vertetippour afficher un message de type ‘astuce’ qui aura une teinte jaune.warningpour afficher un message de type ‘attention’ qui aura une teinte orangée, jaunâtre.
Bien-sûr, ces teintes dépendent des déclarations CSS .
Le shortcode en lui-même :
Source brute vers le shortcode : note
{{ $class := .Get 0 }}{{ $wrd := T (printf "alert-%s" $class) }}
<div class="info-tab {{ $class }}-icon">{{ $wrd }}</div><div class="alert alert-{{ $class }}" role="alert">{{ .Inner | .Page.RenderString }}</div>
L’appel du shortcode est :
Code : shortcode
{{< note id >}}
Ceci est un message
{{< /note >}}
Exemples :
Tag
Ce shortcode n’existe pas pour gérer les tags générés par Hugo, mais pour
gérer l’URL d’un tag au sein d’une page
MD
. Le shortcode va
générer un élément
HTML
a adéquat. Il tient compte de la
gestion multilangue du site.
Au sein de la page Markdown, j’intégre un mot qui se veut être un renvoi vers la page tag ad hoc.
Côté
CSS
, j’ai défini l’attribut ::after sur la définition
.tag pour ajouter l’information (tag) précédé du terme en question.
Ce qui permet visuellement de le différencier des autres liens.
Source brute vers le shortcode : tag
{{ $txt := .Get 0 }}{{ $href := "/" | relLangURL}}{{ $href := (printf "%s%s%s" $href "/tags/" $txt) | urlize }}<a class="tag" href="{{ $href }}">{{ $txt }}</a>
L’appel du shortcode :
Code : shortcode
{{< tag tag-name >}}
Exemple : le mot Hugo est un lien vers l’ URL des articles contenant le tag “Hugo”.
Autres shortcodes
GoHugo
Pour faire un lien vers la documentation officielle d’Hugo, je me suis amusé à écrire ce shortcode :
Code : shortcode
{{< gohugo n="pagename" s="section" a="anchor-name" >}}
nest le nom de la page dans la documentation du site Gohugo.iosest le nom de la section dans la documentation du site Gohugo.ioaest le nom de l’ancre à cibler dans la page
Source brute vers le shortcode : gohugo
{{ $section := .Get "s" }}{{ $name := .Get "n" }}{{ $anchor := .Get "a" }}<a href="https://gohugo.io/{{ $section }}/{{ $name }}/{{ if $anchor }}#{{ $anchor}}{{ end }}" title="{{ i18n "shortcodeGoHugoTitle" }}{{ humanize $section }} > {{ humanize $name }}">{{ i18n "shortcodeGoHugoDocTitle" }}{{ humanize $section }} > {{ humanize $name }}</a>
Exemple: Le lien vers la page Hugo Documentation : Content management > Shortcodes Hugo.
Voici le shortcode correspondant :
Code : shortcode
{{< gohugo n="shortcodes" s="content-management" >}}
Manpage
Utilisant souvent des renvois vers les manpages officiels d’OpenBSD, je me suis crée le shortcode suivant :
Code : shortcode
{{< man title digit anchor >}}
-
Si un chiffre (
digit) est fourni, le shortcode le restituera à la fois, dans l’ URL reconstituée, que dans le texte affiché.
Dans l’ URL , ce sera de typetxt.digit; le texte affiché aura le chiffre entouré des parenthèses, tel quetxt(digit). -
Si une ancre (
anchor) est fournie, le shortcode la restituera à la fois, dans l’ URL reconstituée, que dans le texte affiché, tel quetxt(digit)#anchor.
Source brute vers le shortcode : man
{{ $txt := .Get 0 }}{{ $nb := .Get 1}}
<a class="man" href="https://man.openbsd.org/{{ $txt }}{{ if $nb }}{{ print "." $nb }}{{ end }}" title="{{ i18n "manpageTitle" }}{{ $txt }}">{{ $txt }}{{ if $nb }}{{ print "(" $nb ")" }}{{ end }}</a>
Exemples :
- Lien vers le manpage Packet Filter : pf(4)
- Autre lien celui vers : httpd(8)
- Un dernier pour la route vers : man
Wikipedia
De même pour l’encyclopédie Wikipédia, le shortcode créé est le suivant :
Code : shortcode
{{< wp "url-article" >}}
Source brute vers le shortcode : wp
{{ $txt := .Get 0 }}{{ $title := print (i18n "wpTitleArticle") $txt }}<a href="https://{{ .Site.Language.Lang }}.wikipedia.org/wiki/{{ $txt }}" title="{{ $title }}">Wikipedia :: {{ $txt }}</a>
Exemples :
- Voici un article de promotion sur OpenBSD WP
- En voici un autre pour Debian WP
- Et, un troisième un peu plus compliqué : Pare-feu_(informatique) WP
Ailleurs
Pour finir, n’hésitez pas à vous amuser avec les shortcodes, faites-vous aider sur le forum de la communauté, malheureusement pour nous francoph(on|il)es, en anglais.