Construirea unui site static cu componente folosind Nunjucks
Publicat: 2022-03-10Este destul de popular în zilele noastre și îndrăznesc să spun o idee al naibii de bună, să construiești site-uri cu componente. În loc să construim pagini întregi una câte una, construim un sistem de componente (gândiți-vă: un formular de căutare, un card de articol, un meniu, un subsol) și apoi punem împreună site-ul cu acele componente.
Cadrele JavaScript precum React și Vue subliniază foarte mult această idee. Dar chiar dacă nu utilizați deloc JavaScript pentru client pentru a construi un site, nu înseamnă că trebuie să renunțați la ideea de a construi cu componente! Folosind un preprocesor HTML, putem construi un site static și, totuși, obținem toate beneficiile abstractizării site-ului nostru și a conținutului său în componente reutilizabile.
Site-urile statice sunt de furie în zilele noastre, și pe bună dreptate, deoarece sunt rapide, sigure și ieftin de găzduit. Chiar și Smashing Magazine este un site static, crezi sau nu!
Să facem o plimbare printr-un site pe care l-am construit recent folosind această tehnică. Am folosit CodePen Projects pentru a-l construi, care oferă Nunjucks ca preprocesor, care a fost perfect pentru treabă.
Un site de patru pagini cu antet, navigare și subsol consistente
Acesta este un microsite. Nu are nevoie de un CMS complet pentru a gestiona sute de pagini. Nu are nevoie de JavaScript pentru a gestiona interactivitate. Dar are nevoie de o mână de pagini care au același aspect.
Numai HTML nu are o soluție bună pentru asta. Ceea ce avem nevoie sunt importuri . Limbi precum PHP fac acest lucru simplu cu lucruri precum <?php include "header.php"; ?>
<?php include "header.php"; ?>
, dar gazdele de fișiere statice nu rulează PHP (intenționat), iar HTML singur nu este de ajutor. Din fericire, putem preprocesa includerile cu Nunjucks.
Este perfect logic să creați un aspect , inclusiv bucăți de HTML reprezentând antetul, navigarea și subsolul. Șablonul Nunjucks are conceptul de blocuri, care ne permit să introducem conținut în acel loc atunci când folosim aspectul.
<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>
Observați că fișierele care sunt incluse sunt denumite ca _file.njk
. Nu este în întregime necesar. Ar putea fi header.html
sau icons.svg
, dar ele sunt denumite astfel deoarece 1) fișierele care încep cu caractere de subliniere sunt puțin o modalitate standard de a spune că sunt parțiale. În CodePen Projects, înseamnă că nu vor încerca să fie compilate singure. 2) Numindu-l .njk
, am putea folosi mai multe lucruri Nunjucks acolo dacă dorim.
Niciunul dintre aceste bucăți nu are nimic special în ele. Sunt doar fragmente de HTML destinate să fie folosite în fiecare dintre cele patru pagini ale noastre.
<footer> <p>Just a no-surprises footer, people. Nothing to see here.<p> </footer>
Făcând astfel, putem face o singură modificare și vom reflecta schimbarea pe toate cele patru pagini.
Utilizarea aspectului pentru cele patru pagini
Acum, fiecare dintre cele patru pagini ale noastre poate fi un fișier. Totuși, să începem cu index.njk
, care în CodePen Projects, va fi procesat automat și va crea un fișier index.html
de fiecare dată când salvați.
Iată ce am putea pune în index.njk
pentru a folosi aspectul și a arunca conținut în acel bloc:
{% extends "_layout.njk" %} {% block content %} <h1>Hello, World!</h1> {% endblock %}
Asta ne va cumpăra o pagină de pornire complet funcțională! Grozav! Fiecare dintre cele patru pagini poate face exact același lucru, dar punând conținut diferit în bloc și avem noi înșine un site mic de patru pagini care este ușor de gestionat.
Pentru înregistrare, nu sunt sigur că aș numi aceste mici bucăți pe care le reutilizam componente . Suntem eficienți și împărțim un aspect în bucăți. Mă gândesc la o componentă mai degrabă ca o bucată reutilizabilă care acceptă date și scoate o versiune unică a acesteia cu acele date. Vom ajunge la asta.
Efectuarea navigației active
Acum că am repetat o bucată identică de HTML pe patru pagini, este posibil să aplicăm CSS unic elementelor de navigare individuale pentru a identifica pagina curentă? Am putea cu JavaScript și uitându-ne la window.location
și așa, dar putem face asta fără JavaScript. Trucul este să puneți o class
pe <body>
unică pentru fiecare pagină și să o folosiți în CSS.
În _layout.njk
, corpul iese un nume de clasă ca variabilă:
<body class="{{ body_class }}">
Apoi, înainte de a numi acel aspect pe o pagină individuală, setăm acea variabilă:
{% set body_class = "home" %} {% extends "_layout.njk" %}
Să presupunem că navigarea noastră a fost structurată ca
<nav class="site-nav"> <ul> <li class="nav-home"> <a href="/"> Home </a> ...
Acum putem viza acel link și aplica un stil special, după cum este necesar, făcând:
body.home .nav-home a, body.services .nav-services a { /* continue matching classes for all pages... */ /* unique active state styling */ }
Ah și acele icoane? Acestea sunt doar fișiere .svg
individuale pe care le-am pus într-un folder și am inclus ca
{% include "../icons/cloud.svg" %}
Și asta îmi permite să le modelez astfel:
svg { fill: white; }
Presupunând că elementele SVG din interior nu au atribute de fill
deja pe ele.
Crearea conținutului în Markdown
Pagina de pornire a microsite-ului meu are o mare parte de conținut. Cu siguranță aș putea scrie și menține asta în HTML în sine, dar uneori este frumos să las acest tip de lucru pe seama lui Markdown. Markdown se simte mai curat de scris și poate puțin mai ușor de privit când este multă copie.
Acest lucru este foarte ușor în CodePen Projects. Am făcut un fișier care se termină în .md
, care va fi procesat automat în HTML, apoi l-am inclus în fișierul index.njk
.
{% block content %} <main class="centered-text-column"> {% include "content/about.html" %} </main> {% endblock %}
Construirea componentelor reale
Să considerăm componentele ca fiind module repetabile care au transmis date pentru a se crea singure. În cadre precum Vue, ați lucra cu componente de fișier unic care sunt biți izolați de HTML șablon, CSS cu scop și JavaScript specific pentru componente. Este super tare, dar microsite-ul nostru nu are nevoie de nimic atât de elegant.
Trebuie să creăm câteva „cărți” bazate pe un șablon simplu, astfel încât să putem construi lucruri ca acesta:
Construirea unei componente repetabile ca aceasta în Nunjucks implică utilizarea a ceea ce ei numesc Macro-uri. Macro-urile sunt delicios de simple. Sunt ca și cum HTML ar avea funcții !
{% macro card(title, content) %} <div class="card"> <h2>{{ title }}</h2> <p>{{ content }}</p> </div> {% endmacro %}
Apoi îl sunați după cum este necesar:
{{ card('My Module', 'Lorem ipsum whatever.') }}
Întreaga idee aici este de a separa datele și marcajul . Acest lucru ne oferă câteva beneficii destul de clare și tangibile:
- Dacă trebuie să facem o modificare la HTML, o putem schimba în macrocomandă și se schimbă oriunde care utilizează acea macrocomandă.
- Datele nu sunt încurcate în marcaj
- Datele ar putea veni de oriunde! Codăm datele direct în apeluri către macrocomenzi, așa cum am făcut mai sus. Sau am putea face referire la unele date JSON și am putea trece peste ele. Sunt sigur că vă puteți imagina chiar o configurație în care acele date JSON provin dintr-un fel de CMS fără cap, proces de construire, funcție fără server, job cron sau orice altceva.
Acum avem aceste carduri repetabile care combină datele și marcajul, exact ceea ce ne trebuie:
Faceți câte componente doriți
Poți să iei această idee și să alergi cu ea. De exemplu, imaginați-vă cum Bootstrap este în esență o grămadă de CSS pe care le urmați modele HTML în care să le utilizați. Puteți face din fiecare dintre aceste modele o macrocomandă și le puteți numi după cum este necesar, în esență componend cadrul.
Puteți cuibări componente dacă doriți, îmbrățișând un fel de filozofie de design atomic. Nunjucks oferă, de asemenea, logică, ceea ce înseamnă că puteți crea componente și variații condiționate doar prin transmiterea diferitelor date.
În site-ul simplu pe care l-am făcut, am făcut o macrocomandă diferită pentru secțiunea de idei a site-ului deoarece implica date puțin diferite și un design de card ușor diferit.
Un caz rapid împotriva site-urilor statice
Aș putea argumenta că majoritatea site-urilor beneficiază de o arhitectură bazată pe componente, dar numai unele site-uri sunt potrivite pentru a fi statice. Lucrez pe o mulțime de site-uri în care a avea limbi back-end este adecvat și util.
Unul dintre site-urile mele, CSS-Tricks, are lucruri precum un utilizator de conectare cu un sistem de permisiuni oarecum complex: forumuri, comentarii, comerț electronic. Deși niciunul dintre aceste lucruri nu oprește total ideea de a lucra static, deseori sunt bucuros că am o bază de date și limbi back-end cu care să lucrez. Mă ajută să construiesc ceea ce am nevoie și păstrează lucrurile sub un singur acoperiș.
Du-te și îmbrățișează Viața Statică!
Amintiți-vă că unul dintre beneficiile construcției în modul în care am făcut-o în acest articol este că rezultatul final este doar o grămadă de fișiere statice. Ușor de găzduit, rapid și sigur. Cu toate acestea, nu a trebuit să renunțăm la lucrul într-un mod prietenos pentru dezvoltatori. Acest site va fi ușor de actualizat și adăugat în viitor.
- Proiectul final este un microsite numit The Power of Serverless for Front-End Developers (https://thepowerofserverless.info/).
- Găzduirea statică a fișierelor, dacă mă întrebați pe mine, este o parte a mișcării fără server.
- Puteți vedea tot codul (și chiar puteți obține o copie pentru dvs.) chiar pe CodePen. Este construit, întreținut și găzduit în întregime pe CodePen folosind CodePen Projects.
- CodePen Projects se ocupă de toate lucrurile Nunjucks despre care am vorbit aici, precum și de lucruri precum procesarea Sass și găzduirea imaginilor, de care am profitat pentru site. Puteți replica același lucru, de exemplu, cu un proces de construire bazat pe Gulp sau Grunt la nivel local. Iată un proiect de genul ăsta pe care l-ai putea învârti.