Fermer

septembre 26, 2020

Simplifiez votre pile avec un générateur de site statique sur mesure


À propos de l'auteur

Bryan est un concepteur, développeur et éducateur passionné par les CSS et les sites statiques. Il travaille activement pour encadrer et enseigner aux développeurs et aux concepteurs la valeur…
En savoir plus sur
Bryan
Robinson

Dans le développement moderne, il existe tellement d’outils formidables pour développer des sites Web, mais ils sont souvent plus que ce qui est nécessaire pour un projet donné. Dans cet article, nous allons explorer comment prendre une humble page HTML et rendre son contenu modifiable dans un CMS sans framework et sans JavaScript côté client.

Avec l'avènement du mouvement Jamstack, les sites à service statique sont devenus toute la rage à nouveau. La plupart des développeurs proposant du HTML statique ne créent pas de HTML natif. Pour avoir une solide expérience de développement, nous nous tournons souvent vers des outils appelés Static Site Generators (SSG).

Ces outils sont livrés avec de nombreuses fonctionnalités qui rendent la création de sites statiques à grande échelle agréable. Qu'ils fournissent des connexions simples à des API tierces comme les sources de données Gatsby's ou fournissent une configuration approfondie comme l'énorme collection de moteurs de modèles 11ty's il y en a pour tous les goûts dans la génération de sites statiques. [19659006] Comme ces outils sont conçus pour des cas d'utilisation divers, ils doivent avoir de nombreuses fonctionnalités. Ces fonctionnalités les rendent puissants. Ils les rendent également assez complexes et opaques pour les nouveaux développeurs. Dans cet article, nous allons ramener le SSG à ses composants de base et créer les nôtres.

Qu'est-ce qu'un générateur de site statique?

Au fond, un générateur de site statique est un programme qui exécute une série de transformations sur un groupe de fichiers pour les convertir en actifs statiques, tels que HTML. Quels types de fichiers il peut accepter, comment il les transforme et quels types de fichiers sortent différencient les SSG.

Jekyll un SSG ancien et toujours populaire, utilise Ruby pour traiter Liquid modèles et fichiers de contenu Markdown en HTML.

Gatsby utilise React et JSX pour transformer les composants et le contenu en HTML. Il va ensuite plus loin et crée une application d'une seule page qui peut être servie de manière statique.

11ty rend le HTML à partir de moteurs de création de modèles tels que Liquid, Handlebars Nunjucks ou JavaScript

Chacune de ces plates-formes a des fonctionnalités supplémentaires pour nous faciliter la vie. Ils fournissent des thèmes, construisent des pipelines, une architecture de plugins, etc. Avec chaque fonctionnalité supplémentaire vient plus de complexité, plus de magie et plus de dépendances. Ce sont des fonctionnalités importantes, bien sûr, mais tous les projets n'en ont pas besoin.

Entre ces trois SSG différents, nous pouvons voir un autre thème commun: données + modèles = site final. Cela semble être la fonctionnalité de base des sites statiques générateurs. C'est la fonctionnalité sur laquelle nous baserons notre SSG.

Fondamentalement, un générateur de site statique est un programme qui effectue une série de transformations sur un groupe de fichiers pour les convertir en éléments statiques, comme HTML. [19659016] La pile technologique de notre nouveau générateur de site statique: Handlebars, Sanity.io et Netlify

Pour créer notre SSG, nous aurons besoin d'un moteur de modèle, d'une source de données et d'un hôte capable d'exécuter notre SSG et de créer notre site. De nombreux générateurs utilisent Markdown comme source de données, mais que se passerait-il si nous allions plus loin et connections nativement notre SSG à un CMS?

Prérequis

  • NodeJS installé
  • Compte Sanity.io
  • Connaissance de Git
  • Connaissance de base de la commande line
  • Connaissance de base du déploiement sur des services comme Netlify.

Note : Pour suivre, vous pouvez trouver le code dans ce référentiel sur GitHub .

Configuration Notre structure de document en HTML

Pour démarrer la structure de notre document, nous allons écrire du HTML brut. Pas besoin de compliquer les choses pour le moment.

Dans la structure de notre projet, nous devons créer un endroit pour vivre nos fichiers source. Dans ce cas, nous allons créer un répertoire src et placer notre index.html à l'intérieur.

Dans index.html nous décrirons le contenu que nous voulons. Ce sera une page à propos relativement simple.



    
    
     Titre de la page! 


    

La page d'accueil personnelle de Bryan Robinson

Quelques pages et contenu de texte riche suivant

Bryan est sur Internet

Gardons cela simple. Nous allons commencer par un h1 pour notre page. Nous suivrons cela avec quelques paragraphes d'informations biographiques, et nous ancrerons la page avec une liste de liens pour en voir plus.

Convertir notre HTML en un modèle qui accepte les données

Après avoir notre structure de base , nous devons mettre en place un processus pour combiner cela avec une certaine quantité de données. Pour ce faire, nous utiliserons le moteur de modèle Handlebars .

Au fond, Handlebars prend une chaîne de type HTML, insère des données via des règles définies dans le document, puis génère une chaîne HTML compilée .

Pour utiliser Handlebars, nous devrons initialiser un package.json et installer le package.

Exécutez npm init -y pour créer la structure d'un fichier package.json avec une valeur par défaut contenu. Une fois que nous avons cela, nous pouvons installer Handlebars.

 npm install handlebars 

Notre script de construction sera un script Node. C'est le script que nous utiliserons localement pour construire, mais aussi ce que notre fournisseur de déploiement et notre hôte utiliseront pour construire notre HTML pour le site en ligne.

Pour démarrer notre script, nous allons créer un index.js et nécessitent deux packages en haut. Le premier est Handlebars et le second est un module par défaut dans Node pour accéder au système de fichiers actuel.

 const fs = require ('fs');
const Handlebars = require ('handlebars'); 

Nous utiliserons le module fs pour accéder à notre fichier source, ainsi que pour écrire dans un fichier de distribution. Pour démarrer notre compilation, nous allons créer une fonction main pour que notre fichier s'exécute lorsqu'il est appelé et une fonction buildHTML pour combiner nos données et notre balisage.

 function buildHTML (filename, Les données) {
  const source = fs.readFileSync (nom de fichier, 'utf8'). toString ();
  modèle de const = Handlebars.compile (source);
  sortie const = modèle (données);

  sortie de retour
}

fonction async main (src, dist) {
  const html = buildHTML (src, {"variableData": "Ceci est des données variables"});
 
  fs.writeFile (destination, html, fonction (err) {
    if (err) return console.log (err);
      console.log ('index.html créé');
  });
}

main ('./ src / index.html', './dist/index.html');[19659049子Lafonction main ()  accepte deux arguments: le chemin vers notre modèle HTML et le chemin nous voulons que notre fichier construit vive. Dans notre fonction principale, nous exécutons  buildHTML  sur le chemin source du modèle avec une certaine quantité de données. 

La fonction build convertit le document source en une chaîne et transmet cette chaîne à Handlebars. Handlebars compile un modèle en utilisant cette chaîne. Nous passons ensuite nos données dans le modèle compilé, et Handlebars rend une nouvelle chaîne HTML remplaçant toutes les variables ou la logique du modèle par la sortie de données.

Nous renvoyons cette chaîne dans notre fonction main et utilisons la ] writeFile méthode fournie par le module du système de fichiers de Node pour écrire le nouveau fichier à l'emplacement spécifié si le répertoire existe.

Pour éviter une erreur, ajoutez un répertoire dist dans votre projet avec un .gitkeep qu'il contient. Nous ne voulons pas valider nos fichiers construits (notre processus de construction le fera), mais nous voudrons nous assurer d'avoir ce répertoire pour notre script.

Avant de créer un CMS pour gérer cette page, confirmons ça marche. Pour tester, nous allons modifier notre document HTML pour utiliser les données que nous venons de lui transmettre. Nous utiliserons la syntaxe de la variable Handlebars pour inclure le contenu variableData .

{{variableData}}

Maintenant que notre HTML a une variable, nous sommes prêts à exécuter notre nœud script.

 node index.js 

Une fois le script terminé, nous devrions avoir un fichier à /dist/index.html . Si nous lisons ouvrir ceci dans un navigateur, nous verrons notre balisage rendu, mais aussi notre chaîne «Ceci est des données variables».

Connexion à un CMS

Nous avons un moyen de rassembler des données avec un modèle, nous avons maintenant besoin d'une source pour nos données. Cette méthode fonctionnera avec n'importe quelle source de données dotée d'une API. Pour cette démonstration, nous utiliserons Sanity.io.

Sanity est une première source de données API qui traite le contenu comme des données structurées. Ils disposent d'un système de gestion de contenu open source pour rendre la gestion et l'ajout de données plus pratiques pour les éditeurs et les développeurs. Le CMS est ce que l’on appelle souvent un CMS «sans tête». Au lieu d'un système de gestion traditionnel où vos données sont étroitement couplées à votre présentation, un CMS headless crée une couche de données qui peut être utilisée par n'importe quel frontend ou service (et peut-être plusieurs en même temps).

Sanity est un service payant , mais ils ont un plan «Standard» qui est gratuit et qui possède toutes les fonctionnalités dont nous avons besoin pour un site comme celui-ci.

Configurer Sanity

Le moyen le plus rapide de démarrer avec un nouveau projet Sanity est d'utiliser la CLI Sanity. Nous allons commencer par l’installer globalement.

 npm install -g @ sanity / cli 

La CLI nous donne accès à un groupe d’assistants pour la gestion, le déploiement et la création. Pour commencer, nous allons exécuter sanity init . Cela nous conduira à travers un questionnaire pour aider à démarrer notre Studio (ce que Sanity appelle leur CMS open-source).

 Sélectionnez un projet à utiliser:
   Créer un nouveau projet
   CMS HTML

Utiliser la configuration de l'ensemble de données par défaut?
   Y // cela crée un jeu de données "Production"

Chemin de sortie du projet:
   studio // ou n'importe quel répertoire dans lequel vous souhaitez que cela vive

Sélectionnez un modèle de projet
   Nettoyer le projet sans schéma prédéfini 

Cette étape créera un nouveau projet et un nouveau jeu de données dans votre compte Sanity, créera une version locale de Studio et liera les données et le CMS ensemble pour vous. Par défaut, le répertoire studio sera créé à la racine de notre projet. Dans les projets à plus grande échelle, vous souhaiterez peut-être le configurer en tant que référentiel distinct. Pour ce projet, il est bon de garder cela lié.

Pour exécuter notre Studio localement, nous allons changer le répertoire dans le répertoire studio et exécuter sanity start . Cela exécutera Studio à localhost: 3333 . Lorsque vous vous connectez, un écran s'affiche pour vous informer que vous avez "Schéma vide". Avec cela, il est temps d'ajouter notre schéma, qui est la façon dont nos données seront structurées et éditées.

Création d'un schéma Sanity

La façon dont vous créez des documents et des champs dans Sanity Studio consiste à créer des schémas dans les schémas /schema.js fichier.

Pour notre site, nous allons créer un type de schéma appelé "À propos des détails". Notre schéma découlera de notre HTML. En général, nous pourrions faire de la plupart de notre page Web un seul champ de texte enrichi, mais il est recommandé de structurer notre contenu de manière découplée. Cela offre une plus grande flexibilité dans la façon dont nous pourrions vouloir utiliser ces données à l'avenir.

Pour notre page Web, nous voulons un ensemble de données qui comprend les éléments suivants:

  • Titre
  • Nom complet
  • Biographie (avec édition de texte enrichi)
  • Une liste de sites Web avec un nom et une URL.

Pour définir cela dans notre schéma, nous créons un objet pour notre document et définissons ses champs. Une liste annotée de notre contenu avec son champ type :

  • Titre - chaîne
  • Nom complet - chaîne
  • Biographie - tableau de «blocs»
  • Liste de sites Web - tableau d'objets avec champs de nom et de chaîne URL.
 types: schemaTypes.concat ([
    /* Your types here! */

    {
        title: "About Details",
        name: "about",
        type: "document",
        fields: [
            {
                name: 'title',
                type: 'string'
            },
            {
                name: 'fullName',
                title: 'Full Name',
                type: 'string'
            },
            {
                name: 'bio',
                title: 'Biography',
                name: 'content',
                type: 'array',
                of: [
                    {
                        type: 'block'
                    }
                ]
            },
            {
                nom: 'externalLinks',
                title: "Réseaux sociaux et liens externes",
                type: 'tableau',
                sur: [
                    {
                        type: 'object',
                        fields: [
                            { name: 'text', title: 'Link text', type: 'string' },
                            { name: 'href', title: 'Link url', type: 'string' }
                        ]
                    }
                ]
            }
        ]
    }
]) 

Ajoutez ceci à vos types de schémas, sauvegardez et votre Studio se recompilera et vous présentera vos premiers documents. À partir de là, nous ajouterons notre contenu au CMS en créant un nouveau document et en remplissant les informations.

Structurer votre contenu de manière réutilisable

À ce stade, vous vous demandez peut-être pourquoi nous avons un «plein nom »et un« titre ». C'est parce que nous voulons que notre contenu ait le potentiel d'être polyvalent. En incluant un champ de nom au lieu d'inclure le nom uniquement dans le titre, nous donnons plus d'utilisation à ces données. Nous pouvons ensuite utiliser les informations de ce CMS pour alimenter également une page de CV ou un PDF. Le champ biographie pourrait être utilisé par programme dans d'autres systèmes ou sites Web. Cela nous permet d'avoir une seule source de vérité pour une grande partie de ce contenu au lieu d'être dicté par le cas d'utilisation directe de ce site particulier.

Tirage de nos données dans notre projet

Maintenant que nous avons rendu nos données disponibles via une API, intégrons-le dans notre projet.

Installer et configurer le client JavaScript Sanity

Tout d'abord, nous devons accéder aux données dans Node. Nous pouvons utiliser le client JavaScript Sanity pour forger cette connexion.

 npm install @ sanity / client 

Cela récupérera et installera le SDK JavaScript. À partir de là, nous devons le configurer pour récupérer les données du projet que nous avons configuré précédemment. Pour ce faire, nous allons configurer un script utilitaire dans /utils/SanityClient.js . Nous fournissons au SDK notre ID de projet et le nom de l'ensemble de données, et nous sommes prêts à l'utiliser dans notre script principal.

 const sanityClient = require ('@ sanity / client');
client const = sanityClient ({
    projectId: '4fs6x5jg',
    ensemble de données: 'production',
    useCdn: vrai
  })

module.exports = client; 

Récupération de nos données avec GROQ

De retour dans notre fichier index.js nous allons créer une nouvelle fonction pour récupérer nos données. Pour ce faire, nous utiliserons le langage de requête natif de Sanity, le GROQ open-source .

Nous allons créer la requête dans une variable, puis utiliser le client que nous avons configuré pour récupérer les données en fonction sur la requête. Dans ce cas, nous construisons un objet avec une propriété appelée sur . Dans cet objet, nous voulons renvoyer les données de notre document spécifique. Pour ce faire, nous effectuons une requête basée sur le document _id qui est généré automatiquement lorsque nous créons notre document.

Pour trouver le document _id nous naviguons vers le document dans Studio et copiez-le depuis l'URL ou passez en mode «Inspecter» pour afficher toutes les données du document. Pour entrer dans Inspect, cliquez sur le menu «kabob» en haut à droite ou utilisez le raccourci Ctrl + Alt + I . Cette vue listera toutes les données de ce document, y compris notre _id . Sanity retournera un tableau d'objets document, donc pour simplifier, nous retournerons l'entrée 0th .

Nous transmettons ensuite la requête à la méthode fetch de notre client Sanity et il renverra un objet JSON de toutes les données de notre document. Dans cette démo, renvoyer toutes les données n'est pas un gros problème. Pour les implémentations plus importantes, GROQ permet une « projection » facultative pour ne renvoyer que les champs explicites souhaités.

 const client = require ('./ utils / SanityClient') // en haut de la fichier

// ...

fonction asynchrone getSanityData () {
    requête const = `{
        "à propos de": * [_id == 'YOUR-ID-HERE'][0]
    } `
    let data = attendre client.fetch (requête);
} 

Conversion du champ de texte enrichi en HTML

Avant de pouvoir renvoyer les données, nous devons effectuer une transformation sur notre champ de texte enrichi. Alors que de nombreux CMS utilisent des éditeurs de texte enrichi qui renvoient directement du HTML, Sanity utilise une spécification open-source appelée Portable Text . Le texte portable renvoie un tableau d'objets (pensez au texte enrichi comme une liste de paragraphes et d'autres blocs multimédias) avec toutes les données sur le style du texte enrichi et les propriétés telles que les liens, les notes de bas de page et d'autres annotations. Cela permet à votre texte d'être déplacé et utilisé dans des systèmes qui ne prennent pas en charge HTML, comme les assistants vocaux et les applications natives.

Pour notre cas d'utilisation, cela signifie que nous devons transformer l'objet en HTML . Il existe des modules NPM qui peuvent être utilisés pour convertir du texte portable en diverses utilisations. Dans notre cas, nous utiliserons un package appelé block-content-to-html .

 npm install @ sanity / block-content-to-html 

Ce package affichera tout le balisage par défaut à partir de l'éditeur de texte enrichi. Chaque type de style peut être remplacé pour se conformer au balisage dont vous avez besoin pour votre cas d'utilisation. Dans ce cas, nous laisserons le package faire le travail à notre place.

 const blocksToHtml = require ('@ sanity / block-content-to-html'); // Ajouté en haut

fonction asynchrone getSanityData () {
    requête const = `{
        "à propos de": * [_type == 'about'][0]
    } `
    let data = attendre client.fetch (requête);
    data.about.content = blocksToHtml ({
        blocs: data.about.content
    })
    retourner attendre les données
} 

Utilisation du contenu de Sanity.io dans Handlebars

Maintenant que les données sont dans une forme que nous pouvons utiliser, nous allons passer ceci à notre fonction buildHTML comme argument de données. [19659046] fonction async main (src, dist) {
const data = attendre getSanityData ();
const html = buildHTML (src, données)

fs.writeFile (dist, html, fonction (err) {
if (err) return console.log (err);
console.log ('index.html créé');
});
}

Maintenant, nous pouvons changer notre HTML pour utiliser les nouvelles données. Nous utiliserons davantage d'appels de variable dans notre modèle pour extraire la plupart de nos données.

Pour rendre notre variable de contenu de texte enrichi nous devons ajouter une couche supplémentaire d'accolades à notre variable. Ceci indiquera à Handlebars de restituer le HTML au lieu d'afficher le HTML sous forme de chaîne.

Pour notre tableau externalLinks nous devrons utiliser la fonction de bouclage intégrée de Handlebars pour afficher tous les liens que nous ajouté à notre Studio.




    
    
     {{about.title}} 


    

La page d'accueil personnelle de {{about.fullName}}

{{{about.content}}}

Bryan est sur Internet

Configuration du déploiement

Mettons cela en ligne. Nous avons besoin de deux composants pour que cela fonctionne. Premièrement, nous voulons un hôte statique qui construira nos fichiers pour nous. Ensuite, nous devons déclencher une nouvelle version de notre site lorsque le contenu est modifié dans notre CMS.

Déploiement sur Netlify

Pour l'hébergement, nous utiliserons Netlify. Netlify est un hôte de site statique. Il sert des actifs statiques, mais possède des fonctionnalités supplémentaires qui permettront à notre site de fonctionner correctement. Ils ont une infrastructure de déploiement intégrée qui peut exécuter notre script de nœud, des webhooks pour déclencher des builds, et un CDN distribué à l'échelle mondiale pour s'assurer que notre page HTML est servie rapidement.

Netlify peut regarder notre référentiel sur GitHub et créer un build basé sur une commande que nous pouvons ajouter dans leur tableau de bord.

Tout d'abord, nous devrons pousser ce code sur GitHub. Ensuite, dans le tableau de bord de Netlify, nous devons connecter le nouveau référentiel à un nouveau site dans Netlify .

Une fois que cela est connecté, nous devons dire à Netlify comment construire notre projet. Dans le tableau de bord, nous allons accéder à Paramètres> Créer et déployer> Paramètres de compilation. Dans cette zone, nous devons changer notre «commande de construction» en «noeud index.js» et notre «répertoire de publication» en «./dist[

.) Lorsque Netlify construit notre site, il exécutera notre commande puis vérifiera le dossier que nous listons pour le contenu et publions le contenu à l'intérieur.

Configurer un Webhook

Nous devons également dire à Netlify de publier une nouvelle version quand quelqu'un met à jour le contenu. Pour ce faire, nous allons mettre en place un Webhook pour informer Netlify que nous avons besoin de la reconstruction du site. Un Webhook est une URL à laquelle un autre service (tel que Sanity) peut accéder par programme pour créer une action dans le service d'origine (dans ce cas Netlify).

Nous pouvons configurer un «hook de construction» spécifique dans notre Netlify tableau de bord dans Paramètres> Créer et déployer> Créer des crochets. Ajoutez un hook, donnez-lui un nom et enregistrez. Cela fournira une URL qui peut être utilisée pour déclencher à distance une compilation dans Netlify.

Ensuite, nous devons dire à Sanity de faire une requête à cette URL lorsque vous publiez des modifications.

Nous pouvons utiliser la CLI Sanity pour accomplir cette. Dans notre répertoire / studio nous pouvons exécuter sanity hook create pour nous connecter. La commande demandera un nom, un ensemble de données et une URL. Le nom peut être celui que vous souhaitez, l'ensemble de données doit être production pour notre produit et l'URL doit être l'URL fournie par Netlify.

Désormais, chaque fois que nous publions du contenu dans Studio, notre site Web sera automatiquement mis à jour. Aucun cadre nécessaire.

Étapes suivantes

Voici un très petit exemple de ce que vous pouvez faire lorsque vous créez votre propre outillage. Bien que des SSG plus complets puissent être ce dont vous avez besoin pour la plupart des projets, la création de votre propre mini-SSG peut vous aider à mieux comprendre ce qui se passe dans le générateur de votre choix.

  • Ce site ne publie qu'une page, mais avec un petit supplément dans notre script de construction, nous pourrions le faire publier plus de pages. Il pourrait même publier un article de blog.
  • «L'expérience développeur» fait un peu défaut dans le référentiel. Nous pourrions exécuter notre script Node sur n'importe quel fichier sauvegardé en implémentant un package comme Nodemon ou ajouter un «rechargement à chaud» avec quelque chose comme BrowserSync .
  • Les données qui vivent dans Sanity peuvent alimenter plusieurs sites et services. Vous pouvez créer un site de CV qui l'utilise et publie un fichier PDF au lieu d'une page Web.
  • Vous pouvez ajouter du CSS et donner à ce site l'apparence d'un vrai site.