Hugo : Menu de navigation (simple ou dropdown)

Article publié, le
8 minute(s) de lecture

Cet article contient 1569 mots.
Source brute de l'article : MD

Description

Le but de cet article est de montrer comment créer un menu de navigation pour le SSG qu’est Hugo.

Nous verrons deux manières différentes pour créer :

Info

Documentation

La documentation officielle en anglais :

Configuration

Les différentes entrées du menu sont écrites dans le fichier de configuration config.toml. Pour information, il existe deux autres formats, JSON et YAML. Nous partirons, du prédicat, d’un site n’ayant qu’une seule langue. Si la conception d’un menu multilangue est subtilement différente, le fonctionnement reste exactement le même.

  • Un site monolangue se configure par le biais de l’entrée : menu
  • Là, où un site multilangue se configure par l’entrée : languages

Par défaut, Hugo génére un site pour la langue anglaise ; pour le paramètrer dans votre langue native, il faut modifier au moins la variable defaultContentLanguage, par exemple pour la langue française :
defaultContentLanguage = "fr",
qui peut agrémentée de la variable languageCode = "fr-FR".

Généralement, le fichier HTML sera crée dans le répertoire layouts/partials/, et quelque soit son nom, pour l’exemple, nous l’appelerons nav.html par soucis de simplicité, il sera appelé depuis le fichier layouts/_default/baseof.html.

{{ partial "nav.html" . }}

C’est typiquement le genre de menu qui renvoie vers des éléments au sein de la page, mais il est possible de renvoyer vers une page nommée.

Pour exemple : http://huc.fr.eu.org

Monolangue

Fichier : config.toml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
[menu]
    [[menu.main]]
        identifier  = "who"
        name        = "Qui"
        pre        = ""
        url         = "#whoiam"
        weight     = 1
    [[menu.main]]
        identifier  = "act"
        name        = "Quoi"
        pre        = ""
        url         = "#projects"
        weight     = 2
    [[menu.main]]
        identifier  = "contact"
        name        = "Contact"
        pre        = ""
        url         = "#contact"
        weight     = 3

On remarque donc la présence de variables strictement nécessaires :

  • identifier : un identifiant, strictement nécessaire et unique à chaque entrée
  • name : le nom
  • url : le nom de l’ancre, ou de la page, à cibler. La présence du symbole # signifie que le lien ciblé est une ancre dans la page ; son absence cible un article précisément nommé.

Ainsi que de certaines utiles :

  • weight : c’est le poids du lien dans le menu, plus le poids est faible, plus le lien est “important”.
  • pre : permet d’injecter du code avant le texte.
  • post : permet d’injecter du code après le texte - n’est pas présentée ici

Le reste, sachant qu’il existe d’autres variables, je vous renvoie à la documentation officielle.

Multilangue

Fichier : config.toml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[languages]
    [languages.en]
        homeText = ""
        languageName = "English"
        weight = 2

    [[languages.en.menu.main]]
        identifier  = "who"
        name        = "Who I am"
        pre        = ""
        url         = "#whoiam"
        weight     = 1
    [[languages.en.menu.main]]
        identifier  = "act"
        name        = "Projects"
        pre        = ""
        url         = "#projects"
        weight     = 2
    [[languages.en.menu.main]]
        identifier  = "contact"
        name        = "Contact"
        pre        = ""
        url         = "#contact"
        weight     = 3

    [languages.fr]
        homeText = ""
        languageName = "Français"
        weight = 1

    [[languages.fr.menu.main]]
        identifier  = "who"
        name        = "Qui"
        pre        = ""
        url         = "#whoiam"
        weight     = 1
    [[languages.fr.menu.main]]
        identifier  = "act"
        name        = "Quoi"
        pre        = ""
        url         = "#projects"
        weight     = 2
    [[languages.fr.menu.main]]
        identifier  = "contact"
        name        = "Contact"
        pre        = ""
        url         = "#contact"
        weight     = 3

Bien-sûr, allez lire la documentation officielle !

Structure

Attention

Admettons que vous voulez diriger vers des pages, et non pas des ancres… il vous faudra donc créer dans le répertoire content les articles correspondants portant les noms servant de valeur à la variable url.

Exemple :

Code : sh

content/
    contact.md
    projects.md
    whoiam.md

Bien sûr, il est possible de mixer liens vers des pages et des ancres. À vous de modifier en conséquence…

HTML

Fichier : layout/partials/nav.html

1
2
3
4
5
6
7
8
<div id="nav-border" class="container">
    <nav id="nav" class="nav justify-content-center">
    {{ range .Site.Menus.main }}
    {{ $text := print .Name | safeHTML }}
    <a class="nav-link" href="{{ .URL }}">{{ $text }}</a>
    {{ end }}
    </nav>
</div>

On parcourt tout simplement l’ensemble de la variable .Site.Menus.main pour restituer le code correspondant.

Maintenant si dans le fichier de configuration, vous ajoutez et remplissez la variable pre, il vous faudra modifier le fichier HTML ainsi, par exemple :

{{ $icon := printf "<i class=\"%s\"></i>" .Pre }}
{{ $text := print $icon " " .Name | safeHTML }}

Cet exemple nous permet d’injecter du code HTML afin d’ajouter une icône avant le texte, ce qui est utile dans le contexte de la bibliothèque Font Awesome ou de toute autre semblable.

Info

Pour obtenir un menu dropdown, tel que vous voyez en haut de page sur ce site , le plus simple est d’utiliser le framework Bootstrap.

En tenant compte du fait que vous savez intégrer la bibliothèque JS et la feuille CSS

Structure

Dans le répertoire content, il est nécessaire :

  • de créer un ou plusieurs sous-répertoires, qui correspondront aux sections
  • de créer un ou plusieurs répertoires enfants, dans ces premiers sous-répertoires, qui correspondront aux sous-sections

Voici un exemple de structure de répertoires :

Code : sh

content/
    dev/
        _index.md
        javascript/
            _index.md
            article.md
        python/
            _index.md
            article.md
        shell/
            _index.md
            article1.md
            article2.md
            article3.md

On remarque la présence de fichier _index.md dans chaque répertoire. Le nom des fichiers article*.md n’a pas d’importance.

De même le nom des répertoires importe peu en soit, par contre veillez bien à la correspondance avec la variable url dans le fichier de configuration.

Fichier _index.md

Chaque répertoire a son propre fichier _index.md dont le but est simplement d’activer le répertoire qui doit comporter à minima le Front Matter, au format YAML , qui suit :

Fichier : _index.md

1
2
3
4
5
---
title: "Title"
date: 2019-11-28T23:40:14+01:00
draft: false
---

Si vous voulez qu’il ne soit pas indexé, rajouter la variable noindex: true. (ce qui est évidemment utile dans le contexte de génération de flux de syndication).

Fichier config.toml

La structure du fichier de configuration est sensiblement la même !

Fichier : config.toml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[menu]
    [[menu.main]]
        identifier  = "dev"
        name        = "Développement"
        pre        = ""
        url         = "dev"
        weight     = 1
    [[menu.main]]
        identifier  = "shell"
        name        = "Shell"
        parent      = "dev"
        pre        = ""
        url         = "shell"
        weight     = 10
    [[menu.main]]
        identifier  = "js"
        name        = "JavaScript"
        parent      = "dev"
        pre        = ""
        url         = "javascript"
        weight     = 11
    [[menu.main]]
        identifier  = "py"
        name        = "Python"
        parent      = "dev"
        pre        = ""
        url         = "python"
        weight     = 12

On remarque tout particulièrement :

  • la présence des variables parent qui permettent de définir que l’entrée de menu en question a pour parent celui qui porte l’identifiant nommé. Dans cet exemple, elles ont pour valeur dev et renvoie à l’entrée de menu qui a identifier = "dev", qui est bien aussi leur répertoire parent, dans la structure de répertoires .

Si vous avez un site multilangue , il faudra adapter l’exemple ci-dessus pour le faire correspondre…

HTML

Fichier : layout/partials/nav.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!-- Navbar -->
    <nav class="navbar navbar-expand-lg navbar-transparent">
        <div class="container">
            <div class="navbar-translate">
                <a class="navbar-brand" href="{{ relLangURL "/" }}" rel="tooltip" title="{{.Site.Title}}" data-placement="bottom">
                    {{.Site.Title}}
                </a>
                <button class="navbar-toggler navbar-toggler" type="button" data-toggle="collapse" data-target="#navigation" aria-controls="navigation-index" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-bar bar1"></span>
                    <span class="navbar-toggler-bar bar2"></span>
                    <span class="navbar-toggler-bar bar3"></span>
                </button>
            </div>
            <div class="collapse navbar-collapse justify-content-end" id="navigation">
              <ul class="navbar-nav ml-auto">
      {{ range .Site.Menus.main }}
        {{ if .HasChildren }} {{ $id := print "navbarDropdownMenuLink" .Identifier }}
        <li class="nav-item dropdown">
          <a href="#" class="nav-link dropdown-toggle"  id="{{ $id }}" data-toggle="dropdown">
            {{ .Pre }} <span>{{ .Name }}</span>
            <span class="caret"></span>
          </a>
          <div class="dropdown-menu dropdown-menu-right" aria-labelledby="{{ $id }}">
            {{ range .Children }}
            <a class="dropdown-item" href="{{ .URL | relLangURL }}"{{ if $.IsHome }} data-target="{{ .URL }}"{{ end }}>{{ .Name }}</a>
            {{end}}
          </div>
        </li>
        {{ else }}
        <li class="nav-item">
          <a class="nav-link" href="{{ .URL | relLangURL }}"{{ if $.IsHome }} data-target="{{ .URL }}"{{ end }}>{{ .Name }}</a>
        </li>
        {{ end }}
      {{ end }}
                </ul>
            </div>
        </div>
    </nav>
    <!-- End Navbar -->

Clap de Fin

“Voilà, c’est fini !”

Nous avons ainsi vu comment créer un menu simple ou un menu dropdown pour Hugo.

N’oubliez pas de vous amuser, puis de publier vos articles, et si besoin de vous faire aider par la communauté anglaise de Hugo.


Enjoy-ID!
Enjoy-IT!