Zola est un générateur de sites statiques en Rust. Il convient parfaitement pour réaliser des blogs, des sites vitrines, des galeries... Il possède un système de templating, Tera, qui permet de créer ou d'utiliser des thèmes et de personnaliser à souhait son site, sans restrictions. L'avantage d'utiliser Zola en comparaison avec un site fait à la main, en pur HTML/CSS, c'est qu'il est possible d'écrire ses pages en Markdown, sans coder. Ainsi, une fois l'apparence du site réalisée, il n'est plus nécessaire de toucher au HTML/CSS pour ajouter des articles.
Afin de m'y retrouver à l'avenir, et de peut-être vous éclairer un peu plus sur l'utilisation de Zola, j'ai décidé de regrouper des conseils et indications utiles dans cet article. Ce tutoriel ne vise pas à être complet, loin de là. Il ne remplace pas la documentation de Zola. Il permet simplement, je l'espère, d'y voir un peu plus clair pour débuter et de répertorier les quelques "astuces" que j'ai pu découvrir.
⚠️ Des notions de CSS et de HTML sont nécessaires à la bonne compréhension de ce tutoriel.
Installation
Les différentes installations possibles sont décrites ici. La solution que j'ai choisie, personnellement, est d'avoir téléchargé les sources et de les avoir compilées. Cette solution nécessite cependant d'avoir déjà Rust et Cargo installés.
Utilisation du binaire Zola
Paraphraser la documentation étant inutile, je ne liste ici que les commandes qui m'ont servies.
zola init [nom du site]
va créer un dossier [nom du site] contenant tous les fichiers et dossiers utiles au bon fonctionnement de Zola. Ces fichiers seront décrits plus bas. Lors de l'initialisation, quelques questions vous seront posées, par exemple quelle sera l'URL de votre site. Vos réponses sont modifiables dans le fichier config.toml
.
zola serve
va mettre le site en ligne en local. Il sera donc accessible depuis un navigateur, à l'adresse http://127.0.0.1:1111
. Il est possible de changer l'IP et le port avec les arguments -u
et -p
. La liste des arguments s'obtient avec zola serve --help
.
Avec cette commande, vous pouvez travailler sur votre site, voir les changements s'effectuer automatiquement au fur et à mesure.
⚠️ Attention cependant, si la modification de fichiers permettra de voir l'évolution en direct depuis votre navigateur, la suppression ou la création de fichiers risquent de nécessiter le redémarrage de Zola pour s'afficher correctement.
zola build
va créer un dossier public
dans lequel se trouveront tous les fichiers de votre site web. C'est la commande à réaliser lorsque vous avez terminé votre site. Vous n'aurez ensuite plus qu'à déplacer ce dossier public là où sera hébergé votre site web. Félicitations !
Organisation du dossier du site
Lorsque vous avez utilisé zola init
, Zola vous crée tous les fichiers et dossiers nécessaires à son fonctionnement. Les voici :
-
le dossier
content
contiendra tous les fichiers Markdown de votre site, ainsi que les images associées à vos pages. Son organisation est décrite plus bas. -
le dossier
public
, comme décrit plus haut, sera généré avec la commandezola build
et contiendra toutes les pages, assets et autres fichiers de votre site. -
le dossier
sass
contiendra toutes les feuilles de style que vous utiliserez pour votre site. Elles se terminent en.scss
: il ne s'agit pas de fichiers CSS mais de fichiers SASS : vous pouvez y écrire du CSS avec des règles supplémentaires, dans le but de simplifier votre travail et votre code. Pour ma part, ne maîtrisant pas vraiment SASS, j'ai réalisé entièrement mon site en ne faisant que du CSS sans m'en préoccuper davantage.⚠️ Attention, Zola compilera vos fichiers SASS à la construction du site, et les transformera en fichiers CSS, donc lorsque vous appellez vos feuilles de CSS dans vos templates, ne les appellez pas
fichier.scss
telles qu'elles sont dans le dossier sass, maisfichier.css
. -
le dossier
static
contiendra les éléments qui seront à la racine de votre site, et donc accessibles partout : des polices, des images utilisées régulièrement, votre logo...⚠️ Attention cependant à ne pas mettre toutes les images de votre site dans ce dossier par facilité : il deviendrait surchargé et il serait compliqué de vous y retrouver par la suite.
-
le dossier
templates
contiendra tous vos fichiers HTML. Dans l'idéal, ces fichiers seront des templates : des fichiers qui servent pour plusieurs pages, par exemplearticle.html
qui servira pour tous vos articles, ou alorsnavbar.html
qui servira uniquement pour la barre de navigation, qui s'affiche sur toutes les pages de votre site. Bien sûr, cela n'est pas un problème si un fichier HTML ne sert que pour une seule page. Par exemple, ma page Contact, ou encore À propos, possèdent des fichiers HTML pour elles seules.Il est cependant important de garder à l'esprit l'idée de "templating" : réutiliser des fichiers entiers ou des morceaux de codes à différents endroits pour alléger la structure de son site et la charge de travail. Pensez donc régulièrement à vous poser la question, selon le contexte, si cela ne serait pas plus clair et efficace de cette manière. Il est également possible de retrouver des dossiers dans ce dossier
templates
, il s'agit de "taxonomies". J'en parlerai plus bas. -
le dossier
themes
vous permettra d'utiliser un thème tout prêt pour votre site internet. La liste des thèmes est retrouvable ici. Vous aurez juste à glisser le dossier du thème dans ce dossierthemes
. Pour ma part, j'avais commencé mon site en utilisant le thème after dark, mais je l'ai au fur et à mesure remplacé par un thème fait à la main, jusqu'à totalement le supprimer. -
et enfin, le fichier
config.toml
. Comme son nom l'indique, il s'agit d'un fichier de configuration. C'est ici que vous pourrez modifier l'URL de votre site, le titre, la description, le thème, si vous souhaitez générer des flux RSS ou non, les taxonomies... Je vous renvoie vers la documentation pour plus d'information à ce sujet. Il est également possible, dans la partie[extra]
, de définir vos propres variables pour les utiliser ensuite.
Voici un schéma synthétisant l'organisation des dossiers du site web :
Architecture du site et dossier content
Le dossier content
est, à mon sens, le plus important, puisque c'est lui qui contiendra toutes les pages de votre site. Son architecture, un peu particulière, m'a donné quelques difficultés. Tout d'abord, sachez qu'il existe deux types de "pages web" possibles : les sections et les pages.
En comparaison avec les pages simples, classiques, les sections sont des pages web qui listent, regroupent d'autres pages. Par exemple, le blog et la page "Projets" de mon site sont des sections, puisqu'ils regroupent respectivement des articles et des pages. Le Portfolio est un exemple d'utilisation encore un peu plus poussée des sections : il s'agit d'une section comportant trois sections (les catégories du Portfolio : croquis, illustrations et logos) comportant elles-mêmes différentes sections (par exemple la catégorie "croquis" du Portfolio comporte deux sous-catégories : "portraits" et "paysages") qui comportant des pages. L'usage de sous-sections est donc utile pour faire des arborescences de sous-catégories.
Afin de mieux se visualiser ce concept de pages et de sections, voici un schéma de l'architecture de brume.ink
Les sections seront des dossiers composés de plusieurs dossiers (les pages de la section ou des sous-sections), de pages en .md
, d'assets (images, ...) et d'un fichier _index.md
.
Les pages seront soit des dossiers contenant des assets et un fichier index.md
, soit directement des fichiers dans la section parente en .md.
Les fichiers index.md
et _index.md
se composent de deux parties :
- une partie en haut du fichier contenant des informations sur la page : le titre, la date, la description...
- le contenu de la page, en Markdown.
Cette partie en haut de page est construite de la manière suivante :
+++
title = "Un titre"
description = "Une description"
...
+++
Les informations sont entourées de +++
.
⚠️ Attention, si le fichier ne commence pas par +++
, cela ne fonctionnera pas.
C'est dans cette partie que vous pouvez notamment préciser le template, le fichier HTML que votre page va utiliser : template = "fichier.html"
Nous parlerons des templates plus en détail ci-dessous.
Il y a beaucoup d'options possibles, vous pouvez même créer vos propres variables dans cette partie de cette manière :
[extra]
variable = "valeur"
La liste des options est dans la documentation de Zola.
Templating avec Tera
Tera est un outil de templating. C'est cet outil qui va vous permettre de ne pas avoir à écrire le code HTML de chaque page de votre site. Je vais vous présenter, au travers de quelques exemples, les bases de cet outil et comment l'utiliser. Pour commencer, il existe trois types de délimiteurs lorsque vous utiliserez Tera. Tout code de templating sera compris un de ces délimiteurs.
Le premier, {{ ... }}
sera utilisé pour faire des expressions : appeler un bout de code d'un autre endroit, appeler une variable... par exemple {{ variable }}
va afficher la variable souhaitée. C'est d'une part très pratique pour débugger, mais également pour afficher des informations susceptibles de changer au fil du temps ou en fonction de la page.
Par exemple : vous n'avez qu'un seul fichier HTML qui va servir pour tous les articles. Comment afficher le titre de l'article ? Avec {{ page.title }}
.
Une variable très intéressante pour débugger se nomme __tera_context
: elle affiche toutes les variables de la page et leur contenu. Vous pouvez donc l'afficher avec {{ __tera_context }}
.
Le deuxième, {% ... %}
vous permettra de définir des éléments, comme des variables, ou des blocs.
Le troisième, {# ... #}
permet de mettre du code en commentaire.
⚠️ Attention, les commentaires HTML classiques // commentaire
et <!-- commentaire -->
ne fonctionneront pas sur du code en Tera.
Exemple 1 : créer un template pour un morceau de code qui servira à plusieurs reprises, exemple de la barre de navigation.
Prenez une barre de navigation. Vous souhaitez qu'elle apparaisse sur toutes les pages. Vous pourriez prendre la peine de la copier coller dans chacun de vos fichiers, certes, mais que se passera-t-il, lorsque finalement, vous décideriez de modifier un élément de cette barre ? Vous allez probablement devoir modifier chaque fichier. Ceci n'est pas souhaitable.
Pour remédier à ça, il serait plus judicieux de mettre la barre de navigation dans un fichier séparé, et d'appeler ce fichier dans vos autres fichiers. Ainsi, toute modification dans le fichier de la barre de navigation s'appliquera directement sur tous les autres fichiers !
Créez donc un fichier navbar.html et mettez dedans le code HTML de votre navbar. Vous n'avez ici pas besoin d'expressions de Tera. Ensuite, dans les fichiers où vous souhaitez que la barre de navigation apparaisse, notez simplement {% include "nav.html" %}
.
Et voilà ! Votre barre de navigation a été rajoutée. Vous pouvez faire de même avec un pied de page, un menu... Soyez inventif·ve·s ! Dès que vous avez la sensation de recopier du même code à plusieurs endroits, pensez aux templates.
Exemple 2 : Faire un template modulable qui sert de parent à toutes les pages du site web.
Au début, je ne faisais que des pages distinctes l'unes d'entre elles, puis j'ai remarqué que beaucoup d'éléments dans les pages étaient similaires, à commencer par le header
: la première partie du fichier HTML, où l'on précise toutes sortes d'informations sur la page. J'ai donc réalisé un fichier page_template.html, qui se trouve être le squelette de toutes les autres pages du site.
Dans cette page, on y retrouve des "blocs" : des "parties" de la page web, qui sont soit déjà remplies, soit vides, pour y laisser la place d'y mettre quelque chose. J'ai par exemple, des blocs head, css, header, nav, title, content, footer
. Tout ce qui est sur cette page est contenue dans des blocs.
Le bloc nav, va par exemple contenir la ligne {% include "nav.html" %}
, que nous avons vue plus haut, pour mettre la barre de navigation. Le bloc content est vide, puisque le contenu de la page sera différent pour toutes les pages. Le bloc css contient les feuilles de style utilisées sur l'ensemble du site...
Un bloc commence par {% block ... %}
et termine par {% endblock ... %}
.
Sur toutes mes autres pages, je dis en premier que cette page est dépendante de mon template, de la manière suivante :
{% extends "page_template.html" %}
Je n'ai ensuite plus qu'à modifier les blocs que j'ai besoin. Par exemple, pour rajouter du content à la page, je vais utiliser {% block content %}
et {% endblock content %}
, puis écrire le contenu que je veux. Si le contenu que vous souhaitez mettre est celui d'un fichier en .md
de votre dossier content, alors vous devez entrer la ligne suivante : {{ page.content | safe }}
. De cette manière, votre contenu en Markdown sera donc retranscrit en HTML sur votre page.
Que se passe-t-il quand je souhaite modifier un bloc mais ne pas le réécrire totalement ? Par exemple, je pourrais vouloir rajouter une feuille de style spécialement pour une page, mais garder tout de même les pages qui sont déjà dans ce bloc. Il suffit pour cela d'utiliser {{ super() }}
. Cela va appeler ce qu'il y a dans le bloc parent.
Exemple :
{% block css %}
{{ super() }}
<link rel="stylesheet" href="/fichier.css"/>
{% endblock css %}
Ici, on modifie le bloc css
. On utilise {{ super() }}
avoir les appels de feuilles de style qui étaient dans le fichier page_template.html
, puis on peut rajouter autant de lignes que l'on veut à la suite !
Exemple 3 : utiliser une boucle for
pour répéter un morceau de code et/ou itérer sur des éléments : exemple de la page Projets (code source).
Lorsque vous répétez à plusieurs reprises un élément sur une page web, il peut être intéressant de songer à la boucle for
(le système de Tera vous permet d'utiliser des boucles, et même des conditions).
Prenons donc l'exemple de la page Projets. Il s'agit d'une section comportant plusieurs pages : les pages 42l, et The Blue Frog, à l'heure actuelle. Chacune de ces pages ont une "carte" associée sur la page Projets, qui donne le titre, une image, une description...
Imaginons que vous vouliez faire un blog. C'est une boucle qu'il faudra utiliser pour afficher les différents articles.
Une boucle for
fonctionne de la manière suivante : {% for variable2 in variable1 %}
.
variable1
sera l'élément sur lequel vous voudrez itérer. Dans notre exemple, nous voudrions itérer sur les pages de la section, donc section.pages
. variable2
sera une variable dans laquelle sera stockée la page sur laquelle vous êtes en train d'itérer dans votre boucle.
Appelons-la page
. Cela donne donc :
{% for page in section.pages %}
// code de la carte présentant le projet
{% endfor %}
⚠️ Notez la présence de {% endfor %}
pour mettre fin à votre boucle.
Dans le code de la carte, vous pourrez utiliser des variables propres à la page, que vous avez défini dans votre dossier content, dans un ficher index.md
: un titre, une description... Ces variables se nomment page.title
, page.description
.
Imaginez que vous voulez afficher le titre en grand, vous pourriez par exemple faire :
<h1 class="title">{{project.title}}</h1>
⚠️ Attention, si vous avez mis des variables personalisées dans une partie [extra]
comme décrit plus haut, vous devrez utiliser page.extra.variable
pour y accéder.
N'oubliez pas que pour débugger, vous pouvez utiliser {{ __tera_context }}
pour voir toutes les variables de votre page.
Bonus : Cas des conditions
Si vous voulez exécuter une condition, voir si une variable existe par exemple, vous devrez utiliser un if
.
Voici sa syntaxe :
{% if variable %}
// code exécuté si variable existe
{% else %}
// code exécuté si variable n'existe pas
{% endif %}
Bonus n°2 : Cas des sous-sections (exemple du Portfolio (code source))
Vous pourriez vouloir itérer sur une section, puis sur une sous-section. C'est ce que je fais dans le Portfolio par exemple : j'itère sur les onglets du Portfolio : Croquis, Illustrations, Logos. J'itère ensuite sur les sous-sections de ces sous-sections, pour avoir les différentes parties de ces onglets, comme Portraits et Paysages dans le cas de l'onglet Croquis.
Dans ce cas, vous devrez utiliser des boucles for
imbriquées : une boucle, dans une boucle, dans une boucle... Pour obtenir les variables d'une sous-section, et donc itérer dessus, vous allez devoir utiliser la commande suivante :
{% set variable2 = get_section(path=variable1) %}
Ensuite, vous pourrez éditer sur la variable variable2
, votre sous-section, et ainsi de suite. Je vous invite à regarder le code source donné ci-dessus de la page de Portfolio de mon site pour une utilisation concrète de cette méthode.
Nous avons fait un bon tour de Tera jusqu'à présent. Bien sûr, ce système de templating permet de faire beaucoup plus de choses que ce qui est présenté ici, je vous invite à lire sa documentation pour plus de détails.
Taxonomies et RSS
Votre blog est fin prêt. Vous aimeriez ajouter une dernière petite touche, un flux RSS pour que vos ami·e·s soient au courant de vos derniers articles. Nous allons voir ici comment activer cette fonctionnalité.
Avant de parler de flux RSS, il est important de parler de taxonomies, car Zola, à ma connaissance, forme votre flux RSS en suivant une taxonomie. Qu'est-ce qu'une taxonomie ? Il s'agit d'un moyen de trier, répertorier vos pages. Cela peut par exemple être des catégories, des tags...
Nous allons imaginer ici que vous souhaiteriez créer des catégories pour votre blog. Vos articles peuvent avoir une ou plusieurs catégories. Il est possible de voir la liste des catégories, et de lister les articles par catégorie. Les taxonomies sont faites pour ça !
Commençons par éditer votre fichier config.toml
pour y ajouter les lignes suivantes :
taxonomies = [
{name = "categories"}
}
Nous avons donc une nouvelle taxonomie, que nous avons appelé categories
.
Vous allez ensuite devoir donner des catégories à vos articles ! Allez donc dans le dossier content
, dans les fichiers index.md
de vos articles. Vous allez devoir inscrire dans la partie supérieure du fichier, celle entourée de +++
, les catégories de votre article, de la manière suivante :
+++
title = ...
date = ...
...
[taxonomies]
categories = ["categorie1", "categorie2"]
+++
Ici, votre article aura pour catégories categorie1
et categorie2
. Il ne vous reste plus qu'à faire cela pour tous vos articles !
Vous allez devoir ensuite, dans votre dossier templates
, créer un dossier du nom de la taxonomie, ici categories
. Ce dossier doit contenir deux fichiers : list.html
et single.html
.
list.html
devra afficher la liste de vos catégories. Cette liste se trouve sous forme de tableau (un élément à itérer, donc), dans la variable terms
.
Voici un moyen très simple d'afficher la liste des catégories :
{% for term in terms %}
<a href={{ term.permalink | safe }}">
{{ term.name }}
</a>
{% endfor %}
Dans cet exemple, term.permalink
est le lien de la page où se trouvent tous les articles d'une même catégorie.
single.html
devra afficher tous les articles d'une même catégorie. Pour cela, j'ai repris le code du blog, sauf que je n'ai listé que les articles de la catégorie choisie, de la manière suivante :
{% for page in term.pages %}
// code pour afficher un article avec son image, sa description, son titre...
{% endfor %}
Une fois cela fait, votre système de catégories devrait être parfaitement fonctionnel. Bravo !
Mais, qu'en est-il du RSS ?
Retournez dans le ficher config.toml
à la racine de votre site. Rajoutez (ou éditez si elle existe déjà) la ligne suivante : generate_rss = true
, puis re-modifiez la ligne où vous créez votre taxonomie, pour y ajouter que vous voulez du RSS, comme ceci : {name = "categories", rss = true}
.
Votre flux RSS est créé ! Il se trouve à l'adresse suivante : nom_du_site/rss.xml
.
Conclusion
J'espère que ce tutoriel aura été utile. Si jamais je me mets à utiliser d'autres fonctionnalités de Zola, il n'est pas impossible que je rajoute ou édite des parties.
J'insiste sur le fait que tutoriel est loin d'être parfait. Il n'est pas impossible que des erreurs s'y soient glissées. De plus, il ne se substitue pas à aux documentations officielles de Zola et de Tera.
Il représente simplement la manière dont moi, j'ai conçu mon site, les points que j'ai eu du mal à maîtriser, abordés d'une façon qui, je l'espère, permettra de faciliter le travail à celles et ceux qui pourraient en avoir besoin. N'hésitez pas à me transmettre vos retours sur cet article !
Merci de votre lecture,
Brume.