Comment Creer Un Site Avec Hugo Partie 3 : Le Layout

Aldok

| 7 minutes

Revenir à l'index du tuto : Creer un site avec hugo

Créer un site avec Hugo partie 3 : le layout

Pour l'exemple, nous allons créer un thème basé sur un framework CSS - pour ne pas avoir à réinventer la poudre - le framework Bulma : https://bulma.io/

Ça permettra d'ajouter une charte simple et propre, rapidement et simplement. On reviendra plus tard sur l'utilisation de ce framework css qui est vraiment bien fichu.

Petits ajouts dans le head

Pour ajouter Bulma à la page, il faut d'abord l'appeler, et donc ajouter un lien vers sa feuille de styles minifiée dans head.html.

2 solutions :

  • Soit passer par l'appel distant :
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css">
  • Soit télécharger la feuille de styles, et l'ajouter dans le dossier /css en créant un lien relatif avec la fonction absURL qui va récupérer le chemin absolu du css positionné dans le thème.
<link rel="stylesheet" href="{{ absURL "css/bulma.min.css" }}">

On peut également en profiter pour ajouter quelques icônes avec FontAwesome :

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">

et JQuery pour quelques effets qu'on utilisera plus tard :

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

La partie header

Retournons dans le fichier baseof.html (layouts/_default/baseof.html)

Pour rappel, il s'agit du template qui s'affecte automatiquement à toutes les pages par défaut, si aucun autre template n'est défini.

Voilà ce qu'il doit contenir par défaut :

<!DOCTYPE html>
<html lang="{{ .Site.LanguageCode }}">
    {{- partial "head.html" . -}}
    <body>
        {{- partial "header.html" . -}}
        <main>
            {{- block "main" . }}{{- end }}
        </main>
    {{- partial "footer.html" . -}}
    </body>
</html>

Nous avons déjà rempli la partie head.html, qui contient l'en-tête invisible pour les internautes ; nous allons désormais travailler dans le partial header.html , qui permet de gérer l'apparence du haut du site - qui se répétera donc normalement sur toutes les autres pages.

Rdv dans le fichier layouts/partials/header.html en y ajoutant ce code :

<header>
    <nav class="navbar" role="navigation">
        <div class="container">
            <div class="navbar-brand">
                <a href="/" title="home" class="navbar-item">
                    <span class="logo"><h1>{{ .Site.Title }}</h1></span>
                </a>
                {{ range .Site.Menus.social }}
                <a href="{{ .URL }}" class="navbar-item is-hidden-desktop" title="{{ .Name }}"><span
                        class="icon">{{ .Pre }}</span></a>
                {{ end }}
                <a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
                    <span aria-hidden="true"></span>
                    <span aria-hidden="true"></span>
                    <span aria-hidden="true"></span>
                </a>
            </div>

            <div class="navbar-menu">
                <div class="navbar-start">
                    {{ range .Site.Menus.main }}
                    <a href="{{ .URL }}" class="navbar-item">{{ .Name }}</a>
                    {{ end }}
                </div>
                <div class="navbar-end">
                    {{ range .Site.Menus.social }}
                    <a href="{{ .URL }}" class="navbar-item is-hidden-touch" title="{{ .Name }}"><span
                            class="icon">{{ .Pre }}</span></a>
                    {{ end }}
                </div>
            </div>

        </div>
    </nav>
    <script>
        $(document).ready(function () {
            $(".navbar-burger").click(function () {
                $(".navbar-burger").toggleClass("is-active");
                $(".navbar-menu").toggleClass("is-active");
            })
        })
    </script>
</header>

C'est un gros morceau de code qu'on peut simplifier en le schématisant ainsi :

header
    navbar
        container
            navbar-brand
                navbar-item
                    logo
                navbar-item
                navbar-burger
            navbar-menu
                navbar-start
                    navbar-item
                    navbar-item
                navbar-end
                    navbar-item
                    navbar-item
    script

Les différentes classes utilisées sont des classes propres à Bulma ; pour avoir le détail de ce qu'elles permettent de faire, rdv sur https://github.com/jgthms/bulma/blob/master/css/bulma.css

Tout ce qui se trouve dans la partie haute du site est bien sûr intégrée dans une balise

pour respecter la logique sémantique du html.

Quelques commentaires sur le code du header :

  • La class navbar de Bulma permet de gérer - comme son nom l'indique - l'apparence d'une barre de navigation. Dans cette barre de navigation, on va créer un container qui va permettre de limiter sa largeur totale pour faire en sorte que le logo ne colle pas au bord de l'écran sur des résolutions plus larges.

  • Le container est lui-même constitué de 2 sous-éléments : navbar-brand et navbar-menu.

    • Navbar-brand concerne la partie gauche de la barre de navigation, et va contenir le logo du site, et des icônes sociales qui ne s'afficheront que sur la version mobile grâce à leur class is-hidden-desktop. Idem pour le navbar-burger qui, comme vous vous en doutez, révélera un menu burger sur les versions mobiles du site.

    • Navbar-menu va contenir la partie droite de la partie header.html, qui sera visible sur la version ordinateur mais masquée sur version mobile (puisque c'est le menu burger qui prendra le relai). Vous remarquerez que cet élément est divisé en navbar-start et navbar-end : le premier concerne la partie droite du menu qui va afficher les éléments de la boucle range (et donc les éléments du menu), et navbar-end concerne l'apparence des icônes sociales sur la version desktop - qui se masquera automatiquement sur la version mobile.

  • Enfin, le code se termine par un petit morceau de javascript (jQuery) qui permet de gérer l'apparence du menu burger selon le type d'affichage (desktop ou mobile)

Pour ajouter des liens de navigation de manière dynamique par le biais de la boucle range, il suffit de les déclarer dans le fichier de configuration config.toml :

[[menu.main]]
  name = "A propos"
  url = "/a-propos"

[[menu.main]]
  name = "Blog"
  url = "/blog"

Notez que que si la page “à propos” n'existe pas, il faut la créer pour que le lien fonctionne :-)

Pour activer les icônes sociales, idem, il faut renseigner les liens vers les différents réseaux dans ce fichier de config :

[[menu.social]]
name = "GitHub"
url = "https://github.com/VotreCompteGithub"
pre = "<i class='fab fa-github'></i>"


[[menu.social]]
name = "Twitter"
url = "https://twitter.com/VotreCompteTwitter"
pre = "<i class='fab fa-twitter'></i>"

Comme pour la partie header, il va falloir travailler cette fois dans le fichier layouts/partials/footer.html :

On va ajouter ce code :

<footer class="footer">
    <div class="container">
        <div class="columns has-text-centered">
            {{ range .Site.Menus.footer }}
                <div class="column is-narrow">
                    <a href="{{ .URL }}" class="">{{ .Name }}</a>
                </div>
            {{ end }}
        </div>
    </div>
</footer>

Comme vous pouvez le voir, on utilise la classe footer de Bulma.

On ajoute là aussi un container pour limiter la largeur du footer sur les écrans plus large, dans lequel on ajoute une div avec une classe “columns”, basés sur une architecture en flex (pour + d'infos sur le fonctionnement des colonnes sous Bulma, rdv ici : https://bulma.io/documentation/columns/ )

On va alors créer une boucle qui se répète autant de fois qu'on créera un lien en footer dans le fichier config.toml grâce à la ligne suivante :

{{ range .Site.Menus.footer }}
	<div class="column is-narrow">
		<a href="{{ .URL }}" class="">{{ .Name }}</a>
	</div>
{{ end }}

En gros, ici chaque nouvel élément de menu générera sa propre colonne. Dans config.toml, on renseigne les éléments du footer de cette façon :

[[menu.footer]]
name = "A propos"
url = "/about"

[[menu.footer]]
name = "Protection des données"
url = "/protection-des-donnees"

Le contenu

Maintenant que le header et le footer sont prêts, on va pouvoir s'attaquer au contenu.

On commence par le template de la page d'accueil, layouts/index.html

{{ define "main" }}
<div class="container">
    <div class="section">
        <div class="content">
            {{ .Content }}
        </div>
    </div>
</div>
{{ end }}

Ici, on peut ajouter une classe container pour cadrer un peu mieux le contenu sur les résolutions les plus élevées.

La classe section permet l'ajout d'un padding autour du contenu pour éviter que le texte ne soit trop collé au bord des écrans mobiles.

Ajout de styles personnalisés

Pour ajouter ses propres styles personnalisés en CSS, il est possible de créer une feuille CSS qui viendra surcharger le style courant. Il suffit de créer le fichier style.css dans un dossier static/css.

Ensuite, ajouter cette ligne dans le fichier head.html :

<link rel="stylesheet" href="{{ "css/style.css" | relURL }}" />

Normalement côté front on devrait à ce stade avoir ce visuel :

front-styles-custom

On va pouvoir faire un dernier petit ajustement : pousser le footer en bas de la page (car tant que le site n'est pas rempli il a tendance à se situer un peu haut, pour un pied)

Dans style.css ajoutez par exemple :

body {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

main {
	flex: 1;	
}

Ça permet de transformer body en conteneur flex, qui contient 3 éléments : header, main et footer. Pour que le footer soit “repoussé” en bas de page, il faut que le contenu de main remplisse l'espace inutilisé en hauteur en lui attribuant la valeur flex:1 (Et pour ceux qui se posent la question, comme le conteneur body a une flex-direction en colonne, ça remplit sur la hauteur et non sur la largeur ;-) )

Comme quelques petits rappels concernant flex ne font pas de mal, voilà un lien qui résume assez bien l'ensemble de la “logique” flex : https://css-tricks.com/snippets/css/a-guide-to-flexbox/

C'est tout pour aujourd'hui !

Voilà pour cette partie, notre site commence à ressembler à quelque chose - du moins sa page d'accueil.

Nous allons pouvoir nous attarder désormais aux pages de contenus en commençant par les articles.

Vous devriez également aimer ce qui suit...