Construire un site statique avec des composants à l'aide de Nunjucks

Publié: 2022-03-10
Résumé rapide ↬ Même si vous n'utilisez pas du tout de JavaScript côté client pour construire un site, cela ne signifie pas que vous devez abandonner l'idée de construire avec des composants. Apprenez à créer un site statique à l'aide d'un préprocesseur HTML.

C'est assez populaire de nos jours, et oserais-je dire une sacrée bonne idée, de construire des sites avec des composants. Plutôt que de créer des pages entières une par une, nous construisons un système de composants (pensez : un formulaire de recherche, une carte d'article, un menu, un pied de page) puis nous assemblons le site avec ces composants.

Les frameworks JavaScript comme React et Vue mettent fortement l'accent sur cette idée. Mais même si vous n'utilisez pas du tout de JavaScript côté client pour construire un site, cela ne signifie pas que vous devez abandonner l'idée de construire avec des composants ! En utilisant un préprocesseur HTML, nous pouvons créer un site statique tout en bénéficiant de tous les avantages de l'abstraction de notre site et de son contenu dans des composants réutilisables.

Les sites statiques font fureur ces jours-ci, et à juste titre, car ils sont rapides, sécurisés et peu coûteux à héberger. Même Smashing Magazine est un site statique, croyez-le ou non !

Promenons-nous sur un site que j'ai construit récemment en utilisant cette technique. J'ai utilisé CodePen Projects pour le construire, qui propose Nunjucks comme préprocesseur, ce qui était parfaitement adapté à la tâche.

Un site de quatre pages avec un en-tête, une navigation et un pied de page cohérents

Ceci est un microsite. Il n'a pas besoin d'un CMS complet pour gérer des centaines de pages. Il n'a pas besoin de JavaScript pour gérer l'interactivité. Mais il a besoin d'une poignée de pages qui partagent toutes la même mise en page.

En-tête et pied de page cohérents
En-tête et pied de page cohérents sur toutes les pages
Plus après saut! Continuez à lire ci-dessous ↓

HTML seul n'a pas de bonne solution pour cela. Ce dont nous avons besoin, ce sont des importations . Des langages comme PHP rendent cela simple avec des choses comme <?php include "header.php"; ?> <?php include "header.php"; ?> , mais les hôtes de fichiers statiques n'exécutent pas PHP (à dessein) et HTML seul n'est d'aucune aide. Heureusement, nous pouvons prétraiter les inclusions avec Nunjucks.

Importation de composants dans des pages
L'importation de composants est possible dans des langages comme PHP

Il est parfaitement logique ici de créer une mise en page , comprenant des morceaux de HTML représentant l'en-tête, la navigation et le pied de page. Les modèles de Nunjucks ont le concept de blocs, qui nous permettent d'insérer du contenu à cet endroit lorsque nous utilisons la mise en page.

 <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>The Power of Serverless</title> <link rel="stylesheet" href="/styles/style.processed.css"> </head> <body> {% include "./template-parts/_header.njk" %} {% include "./template-parts/_nav.njk" %} {% block content %} {% endblock %} {% include "./template-parts/_footer.njk" %} </body>

Notez que les fichiers inclus sont nommés comme _file.njk . Ce n'est pas tout à fait nécessaire. Cela pourrait être header.html ou icons.svg , mais ils sont nommés ainsi parce que 1) les fichiers qui commencent par des traits de soulignement sont un peu une façon standard de dire qu'ils sont partiels. Dans CodePen Projects, cela signifie qu'ils n'essaieront pas d'être compilés seuls. 2) En le nommant .njk , nous pourrions utiliser plus de trucs Nunjucks là-dedans si nous le voulons.

Aucun de ces morceaux n'a quoi que ce soit de spécial en eux. Ce ne sont que de petits morceaux de HTML destinés à être utilisés sur chacune de nos quatre pages.

 <footer> <p>Just a no-surprises footer, people. Nothing to see here.<p> </footer>

De cette façon, nous pouvons apporter un changement et faire en sorte que le changement soit reflété sur les quatre pages.

Utilisation de la mise en page pour les quatre pages

Désormais, chacune de nos quatre pages peut être un fichier. Commençons simplement par index.njk , qui dans les projets CodePen, sera automatiquement traité et créera un fichier index.html à chaque fois que vous enregistrerez.

Le fichier index.njk
Commencer avec un fichier index.njk

Voici ce que nous pourrions mettre dans index.njk pour utiliser la mise en page et déposer du contenu dans ce bloc :

 {% extends "_layout.njk" %} {% block content %} <h1>Hello, World!</h1> {% endblock %}

Cela nous achètera une page d'accueil entièrement fonctionnelle ! Agréable! Chacune des quatre pages peut faire exactement la même chose, mais en mettant un contenu différent dans le bloc, et nous avons nous-mêmes un petit site de quatre pages facile à gérer.

Index compilé.html
Le fichier index.njk est compilé dans index.html

Pour mémoire, je ne suis pas sûr d'appeler ces petits morceaux que nous réutilisons des composants . Nous sommes juste efficaces et décomposons une mise en page en morceaux. Je pense à un composant qui ressemble plus à un morceau réutilisable qui accepte des données et produit une version unique de lui-même avec ces données. Nous y viendrons.

Rendre la navigation active

Maintenant que nous avons répété un morceau de code HTML identique sur quatre pages, est-il possible d'appliquer un CSS unique à des éléments de navigation individuels pour identifier la page actuelle ? Nous pourrions avec JavaScript et regarder window.location et autres, mais nous pouvons le faire sans JavaScript. L'astuce consiste à mettre une class sur le <body> unique à chaque page et à l'utiliser dans le CSS.

Dans notre _layout.njk , le corps affiche un nom de classe en tant que variable :

 <body class="{{ body_class }}">

Ensuite, avant d'appeler cette mise en page sur une page individuelle, nous définissons cette variable :

 {% set body_class = "home" %} {% extends "_layout.njk" %}

Disons que notre navigation était structurée comme

 <nav class="site-nav"> <ul> <li class="nav-home"> <a href="/"> Home </a> ...

Nous pouvons maintenant cibler ce lien et appliquer un style spécial selon les besoins en faisant :

 body.home .nav-home a, body.services .nav-services a { /* continue matching classes for all pages... */ /* unique active state styling */ } 
Style d'état actif sur la navigation
Styliser les liens de navigation avec une classe active.

Oh et ces icônes ? Ce ne sont que des fichiers .svg individuels que j'ai mis dans un dossier et inclus comme

 {% include "../icons/cloud.svg" %}

Et cela me permet de les styliser comme:

 svg { fill: white; }

En supposant que les éléments SVG à l'intérieur n'aient pas déjà d'attributs de fill .

Création de contenu dans Markdown

La page d'accueil de mon microsite contient une grande partie du contenu. Je pourrais certainement écrire et maintenir cela en HTML lui-même, mais parfois c'est bien de laisser ce genre de choses à Markdown. Markdown semble plus propre à écrire et peut-être un peu plus facile à regarder quand il y a beaucoup de copie.

C'est très facile dans les projets CodePen. J'ai créé un fichier qui se termine par .md , qui sera automatiquement transformé en HTML, puis inclus celui-ci dans le fichier index.njk .

Markdown compilé en HTML sur les projets CodePen
Les fichiers dans Markdown sont compilés en HTML sur les projets CodePen.
 {% block content %} <main class="centered-text-column"> {% include "content/about.html" %} </main> {% endblock %}

Construire des composants réels

Considérons les composants comme des modules répétables qui sont passés dans les données pour se créer. Dans des frameworks comme Vue, vous travailleriez avec des composants de fichier unique qui sont des morceaux isolés de modèle HTML, de CSS étendu et de JavaScript spécifique au composant. C'est super cool, mais notre microsite n'a pas besoin de quelque chose d'aussi sophistiqué.

Nous devons créer des « cartes » basées sur un modèle simple, afin que nous puissions construire des choses comme ceci :

Composants de style carte
Création de composants reproductibles avec des modèles

La construction d'un composant reproductible comme celui de Nunjucks implique l'utilisation de ce qu'ils appellent des macros. Les macros sont délicieusement simples. C'est comme si HTML avait des fonctions !

 {% macro card(title, content) %} <div class="card"> <h2>{{ title }}</h2> <p>{{ content }}</p> </div> {% endmacro %}

Ensuite, vous l'appelez au besoin:

 {{ card('My Module', 'Lorem ipsum whatever.') }}

L'idée ici est de séparer les données et le balisage . Cela nous donne des avantages assez clairs et tangibles :

  1. Si nous devons apporter une modification au code HTML, nous pouvons le modifier dans la macro et il est modifié partout où cette macro est utilisée.
  2. Les données ne sont pas emmêlées dans le balisage
  3. Les données peuvent provenir de n'importe où ! Nous codons les données directement dans les appels aux macros comme nous l'avons fait ci-dessus. Ou nous pourrions référencer des données JSON et boucler dessus. Je suis sûr que vous pourriez même imaginer une configuration dans laquelle ces données JSON proviennent d'une sorte de CMS sans tête, d'un processus de construction, d'une fonction sans serveur, d'une tâche cron ou autre.

Nous avons maintenant ces cartes répétables qui combinent données et balisage, exactement ce dont nous avons besoin :

Les données et le balisage du composant sont séparés
HTML est contrôlé dans la macro, tandis que les données peuvent provenir de n'importe où

Créez autant de composants que vous le souhaitez

Vous pouvez prendre cette idée et courir avec elle. Par exemple, imaginez comment Bootstrap est essentiellement un tas de CSS que vous suivez des modèles HTML à utiliser. Vous pouvez faire de chacun de ces modèles une macro et les appeler selon vos besoins, en composant essentiellement le framework.

Vous pouvez imbriquer des composants si vous le souhaitez, en adoptant une sorte de philosophie de conception atomique. Nunjucks offre également une logique, ce qui signifie que vous pouvez créer des composants conditionnels et des variations simplement en transmettant différentes données.

Dans le site simple que j'ai créé, j'ai créé une macro différente pour la section des idées du site car elle impliquait des données légèrement différentes et une conception de carte légèrement différente.

Composants de la carte dans la section Idées
Il est possible de créer autant de composants que vous le souhaitez

Un cas rapide contre les sites statiques

Je pourrais dire que la plupart des sites bénéficient d'une architecture basée sur les composants, mais seuls certains sites sont appropriés pour être statiques. Je travaille sur de nombreux sites sur lesquels avoir des langages back-end est approprié et utile.

Un de mes sites, CSS-Tricks, a des choses comme une connexion utilisateur avec un système d'autorisations quelque peu complexe : forums, commentaires, commerce électronique. Bien qu'aucune de ces choses n'empêche totalement l'idée de travailler de manière statique, je suis souvent content d'avoir une base de données et des langages principaux avec lesquels travailler. Cela m'aide à construire ce dont j'ai besoin et à garder les choses sous un même toit.

Allez de l'avant et adoptez la vie statique !

N'oubliez pas que l'un des avantages de la construction de la manière dont nous l'avons fait dans cet article est que le résultat final n'est qu'un tas de fichiers statiques. Facile à héberger, rapide et sécurisé. Pourtant, nous n'avons pas dû renoncer à travailler d'une manière conviviale pour les développeurs. Ce site sera facile à mettre à jour et à ajouter à l'avenir.

  • Le projet final est un microsite appelé The Power of Serverless for Front-End Developers (https://thepowerofserverless.info/).
  • L'hébergement de fichiers statiques, si vous me le demandez, fait partie du mouvement sans serveur.
  • Vous pouvez voir tout le code (et même vous en procurer une copie) directement sur CodePen. Il est construit, maintenu et hébergé entièrement sur CodePen à l'aide de projets CodePen.
  • CodePen Projects gère toutes les choses Nunjucks dont nous avons parlé ici, ainsi que des choses comme le traitement Sass et l'hébergement d'images, dont j'ai profité pour le site. Vous pouvez répliquer la même chose avec, par exemple, un processus de construction basé sur Gulp ou Grunt localement. Voici un projet passe-partout comme celui-là que vous pourriez créer.