Costruire un sito statico con componenti utilizzando Nunjucks

Pubblicato: 2022-03-10
Riassunto veloce ↬ Anche se non utilizzi alcun JavaScript lato client per creare un sito, non significa che devi rinunciare all'idea di costruire con i componenti. Scopri come creare un sito statico con l'aiuto di un preprocessore HTML.

È piuttosto popolare in questi giorni, e oserei dire un'idea dannatamente buona, creare siti con componenti. Invece di costruire intere pagine una per una, costruiamo un sistema di componenti (pensa: un modulo di ricerca, una scheda articolo, un menu, un piè di pagina) e poi uniamo il sito con quei componenti.

Framework JavaScript come React e Vue enfatizzano pesantemente questa idea. Ma anche se non utilizzi alcun JavaScript lato client per creare un sito, ciò non significa che devi rinunciare all'idea di costruire con i componenti! Utilizzando un preprocessore HTML, possiamo creare un sito statico e ottenere comunque tutti i vantaggi dell'astrazione del nostro sito e del suo contenuto in componenti riutilizzabili.

I siti statici sono di gran moda in questi giorni, e giustamente, poiché sono veloci, sicuri e poco costosi da ospitare. Anche Smashing Magazine è un sito statico, che tu ci creda o no!

Facciamo una passeggiata attraverso un sito che ho costruito di recente usando questa tecnica. Ho usato CodePen Projects per costruirlo, che offre Nunjucks come preprocessore, il che era perfetto per il lavoro.

Un sito di quattro pagine con intestazione, navigazione e piè di pagina coerenti

Questo è un microsito. Non ha bisogno di un CMS completo per gestire centinaia di pagine. Non ha bisogno di JavaScript per gestire l'interattività. Ma ha bisogno di una manciata di pagine che condividono tutte lo stesso layout.

Intestazione e piè di pagina coerenti
Intestazione e piè di pagina coerenti in tutte le pagine
Altro dopo il salto! Continua a leggere sotto ↓

L'HTML da solo non ha una buona soluzione per questo. Quello di cui abbiamo bisogno sono le importazioni . Linguaggi come PHP lo rendono semplice con cose come <?php include "header.php"; ?> <?php include "header.php"; ?> , ma gli host di file statici non eseguono PHP (apposta) e l'HTML da solo non è di aiuto. Fortunatamente, possiamo preelaborare include con Nunjucks.

Importazione di componenti nelle pagine
L'importazione di componenti è possibile in linguaggi come PHP

Ha perfettamente senso qui creare un layout , inclusi blocchi di HTML che rappresentano l'intestazione, la navigazione e il piè di pagina. Il modello di Nunjucks ha il concetto di blocchi, che ci consentono di inserire il contenuto in quel punto quando utilizziamo il layout.

 <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>

Si noti che i file inclusi sono denominati come _file.njk . Non è del tutto necessario. Potrebbe essere header.html o icons.svg , ma sono denominati in questo modo perché 1) i file che iniziano con caratteri di sottolineatura sono un modo un po' standard per dire che sono parziali. In CodePen Projects, significa che non proveranno a essere compilati da soli. 2) .njk , potremmo usare più cose di Nunjucks lì dentro se vogliamo.

Nessuno di questi bit ha nulla di speciale in loro. Sono solo piccoli frammenti di HTML destinati ad essere utilizzati in ciascuna delle nostre quattro pagine.

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

In questo modo, possiamo apportare una modifica e far sì che la modifica si rifletta su tutte e quattro le pagine.

Utilizzo del layout per le quattro pagine

Ora ciascuna delle nostre quattro pagine può essere un file. Cominciamo solo con index.njk , che in CodePen Projects verrà elaborato automaticamente e creerà un file index.html ogni volta che salvi.

Il file index.njk
A partire da un file index.njk

Ecco cosa potremmo inserire in index.njk per usare il layout e rilasciare alcuni contenuti in quel blocco:

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

Questo ci comprerà una home page completamente funzionale! Carino! Ognuna delle quattro pagine può fare esattamente la stessa cosa, ma inserendo contenuti diversi nel blocco, e noi stessi abbiamo un piccolo sito di quattro pagine facile da gestire.

index.html compilato
Il file index.njk viene compilato in index.html

Per la cronaca, non sono sicuro che chiamerei questi piccoli pezzi che riutilizziamo i componenti . Stiamo solo essendo efficienti e suddividendo un layout in blocchi. Penso a un componente più simile a un blocco riutilizzabile che accetta dati e genera una versione unica di se stesso con quei dati. Ci arriveremo.

Fare Navigazione Attiva

Ora che abbiamo ripetuto un blocco identico di HTML su quattro pagine, è possibile applicare CSS univoci a singoli elementi di navigazione per identificare la pagina corrente? Potremmo con JavaScript e guardando window.location e simili, ma possiamo farlo senza JavaScript. Il trucco sta nel mettere una class sul <body> univoca per ogni pagina e usarla nel CSS.

Nel nostro _layout.njk abbiamo il corpo di output di un nome di classe come variabile:

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

Quindi, prima di chiamare quel layout su una pagina individuale, impostiamo quella variabile:

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

Diciamo che la nostra navigazione era strutturata come

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

Ora possiamo indirizzare quel collegamento e applicare uno stile speciale secondo necessità eseguendo:

 body.home .nav-home a, body.services .nav-services a { /* continue matching classes for all pages... */ /* unique active state styling */ } 
Stile attivo sulla navigazione
Stile dei collegamenti di navigazione con una classe attiva.

Oh e quelle icone? Questi sono solo singoli file .svg che ho inserito in una cartella e inclusi come

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

E questo mi permette di modellarli come:

 svg { fill: white; }

Supponendo che gli elementi SVG all'interno non abbiano già attributi di fill su di essi.

Creazione di contenuti in Markdown

La homepage del mio microsito ha una grossa fetta di contenuto. Potrei certamente scriverlo e mantenerlo nello stesso HTML, ma a volte è bello lasciare quel tipo di cose a Markdown. Markdown sembra più pulito da scrivere e forse un po' più facile da guardare quando c'è molta copia.

Questo è molto semplice nei progetti CodePen. Ho creato un file che termina con .md , che verrà automaticamente elaborato in HTML, quindi incluso nel file index.njk .

Markdown compilato in HTML su CodePen Projects
I file in markdown vengono compilati in HTML su CodePen Projects.
 {% block content %} <main class="centered-text-column"> {% include "content/about.html" %} </main> {% endblock %}

Costruzione di componenti reali

Consideriamo i componenti come moduli ripetibili che hanno passato i dati per creare se stessi. In framework come Vue, lavoreresti con componenti di file singoli che sono bit isolati di HTML basato su modelli, CSS con ambito e JavaScript specifico del componente. È fantastico, ma il nostro microsito non ha bisogno di nulla di così elegante.

Abbiamo bisogno di creare alcune "carte" basate su un semplice modello, quindi possiamo costruire cose come questa:

Componenti in stile carta
Creazione di componenti ripetibili con modelli

Costruire un componente ripetibile come quello in Nunjucks implica l'uso di ciò che chiamano Macro. Le macro sono deliziosamente semplici. Sono come se l'HTML avesse delle funzioni !

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

Quindi lo chiami secondo necessità:

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

L'idea è quella di separare i dati e il markup . Questo ci dà alcuni vantaggi abbastanza chiari e tangibili:

  1. Se dobbiamo apportare una modifica all'HTML, possiamo cambiarlo nella macro e viene modificato ovunque che utilizzi quella macro.
  2. I dati non sono aggrovigliati nel markup
  3. I dati potrebbero provenire da qualsiasi luogo! Codifichiamo i dati direttamente nelle chiamate alle macro come abbiamo fatto sopra. Oppure potremmo fare riferimento ad alcuni dati JSON e scorrerci sopra. Sono sicuro che potresti persino immaginare una configurazione in cui quei dati JSON provengono da una sorta di CMS senza testa, processo di compilazione, funzione serverless, lavoro cron o altro.

Ora abbiamo queste schede ripetibili che combinano dati e markup, proprio quello di cui abbiamo bisogno:

I dati e il markup per il componente vengono mantenuti separati
L'HTML è controllato nella macro, mentre i dati possono provenire da qualsiasi luogo

Crea tutti i componenti che desideri

Puoi prendere questa idea e correre con essa. Ad esempio, immagina come Bootstrap sia essenzialmente un insieme di CSS che segui i modelli HTML in cui utilizzare. Potresti trasformare ciascuno di questi modelli in una macro e chiamarli secondo necessità, essenzialmente componenti del framework.

Puoi annidare i componenti se lo desideri, abbracciando una sorta di filosofia di progettazione atomica. Nunjucks offre anche la logica, il che significa che puoi creare componenti e variazioni condizionali semplicemente passando dati diversi.

Nel semplice sito che ho creato, ho creato una macro diversa per la sezione delle idee del sito perché prevedeva dati leggermente diversi e un design delle carte leggermente diverso.

Componenti della carta nella sezione Idee
È possibile creare tutti i componenti che vuoi

Un rapido caso contro i siti statici

Potrei sostenere che la maggior parte dei siti trae vantaggio da un'architettura basata su componenti, ma solo alcuni siti sono appropriati per essere statici. Lavoro su molti siti in cui avere lingue di back-end è appropriato e utile.

Uno dei miei siti, CSS-Tricks, ha cose come un login utente con un sistema di autorizzazioni alquanto complesso: forum, commenti, eCommerce. Anche se nessuna di queste cose interrompe completamente l'idea di lavorare in modo statico, spesso sono contento di avere un database e linguaggi di back-end con cui lavorare. Mi aiuta a costruire ciò di cui ho bisogno e mantiene le cose sotto lo stesso tetto.

Vai avanti e abbraccia la vita statica!

Ricorda che uno dei vantaggi della creazione nel modo in cui abbiamo fatto in questo articolo è che il risultato finale è solo un mucchio di file statici. Facile da ospitare, veloce e sicuro. Tuttavia, non dovevamo rinunciare a lavorare in modo amichevole per gli sviluppatori. Questo sito sarà facile da aggiornare e aggiungere in futuro.

  • Il progetto finale è un microsito chiamato The Power of Serverless for Front-End Developers (https://thepowerofserverless.info/).
  • L'hosting di file statici, se me lo chiedi, fa parte del movimento serverless.
  • Puoi vedere tutto il codice (e persino biforcare una copia per te stesso) direttamente su CodePen. È costruito, mantenuto e ospitato interamente su CodePen utilizzando CodePen Projects.
  • CodePen Projects gestisce tutte le cose di Nunjucks di cui abbiamo parlato qui, e anche cose come l'elaborazione Sass e l'hosting delle immagini, di cui ho approfittato per il sito. Potresti replicare lo stesso con, ad esempio, un processo di compilazione basato su Gulp o Grunt in locale. Ecco un progetto standard come quello che potresti far girare.