Erstellen einer statischen Site mit Komponenten unter Verwendung von Nunjucks

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Auch wenn Sie überhaupt kein clientseitiges JavaScript verwenden, um eine Website zu erstellen, bedeutet das nicht, dass Sie die Idee des Erstellens mit Komponenten aufgeben müssen. Erfahren Sie, wie Sie mit Hilfe eines HTML-Präprozessors eine statische Website erstellen.

Heutzutage ist es ziemlich beliebt, und ich wage zu sagen, dass es eine verdammt gute Idee ist, Websites mit Komponenten zu erstellen. Anstatt ganze Seiten einzeln zu erstellen, bauen wir ein System von Komponenten (denken Sie an: ein Suchformular, eine Artikelkarte, ein Menü, eine Fußzeile) und setzen dann die Website mit diesen Komponenten zusammen.

JavaScript-Frameworks wie React und Vue betonen diese Idee stark. Aber selbst wenn Sie überhaupt kein clientseitiges JavaScript verwenden, um eine Site zu erstellen, bedeutet das nicht, dass Sie die Idee des Erstellens mit Komponenten aufgeben müssen! Durch die Verwendung eines HTML-Präprozessors können wir eine statische Website erstellen und dennoch alle Vorteile der Abstraktion unserer Website und ihres Inhalts in wiederverwendbare Komponenten nutzen.

Statische Websites sind heutzutage der letzte Schrei, und das zu Recht, da sie schnell, sicher und kostengünstig zu hosten sind. Sogar Smashing Magazine ist eine statische Seite, ob Sie es glauben oder nicht!

Lassen Sie uns einen Spaziergang durch eine Site machen, die ich kürzlich mit dieser Technik erstellt habe. Ich habe CodePen Projects verwendet, um es zu bauen, das Nunjucks als Präprozessor anbietet, was perfekt für den Job war.

Eine vierseitige Website mit konsistenter Kopf-, Navigations- und Fußzeile

Dies ist eine Microsite. Es braucht kein vollwertiges CMS, um Hunderte von Seiten zu verwalten. Es benötigt kein JavaScript, um die Interaktivität zu handhaben. Aber es braucht eine Handvoll Seiten, die alle das gleiche Layout haben.

Einheitliche Kopf- und Fußzeile
Einheitliche Kopf- und Fußzeile auf allen Seiten
Mehr nach dem Sprung! Lesen Sie unten weiter ↓

HTML allein hat dafür keine gute Lösung. Was wir brauchen, sind Importe . Sprachen wie PHP machen dies einfach mit Dingen wie <?php include "header.php"; ?> <?php include "header.php"; ?> , aber Hosts für statische Dateien führen (absichtlich) kein PHP aus, und HTML allein hilft nicht. Glücklicherweise können wir Includes mit Nunjucks vorverarbeiten.

Importieren von Komponenten in Seiten
Das Importieren von Komponenten ist in Sprachen wie PHP möglich

Hier ist es absolut sinnvoll, ein Layout zu erstellen, das HTML-Blöcke enthält, die die Kopf-, Navigations- und Fußzeile darstellen. Nunjucks Templating hat das Konzept von Blöcken, die es uns ermöglichen, Inhalte an dieser Stelle einzufügen, wenn wir das Layout verwenden.

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

Beachten Sie, dass die enthaltenen Dateien wie _file.njk benannt sind. Das ist nicht unbedingt notwendig. Es könnte header.html oder icons.svg , aber sie werden so benannt, weil 1) Dateien, die mit Unterstrichen beginnen, ein wenig Standard sind, um zu sagen, dass sie partiell sind. In CodePen-Projekten bedeutet dies, dass sie nicht versuchen, alleine kompiliert zu werden. 2) Indem wir es .njk , könnten wir mehr Nunjucks-Zeug darin verwenden, wenn wir wollen.

Keines dieser Bits hat überhaupt etwas Besonderes. Sie sind nur kleine HTML-Stücke, die auf jeder unserer vier Seiten verwendet werden sollen.

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

Auf diese Weise können wir eine Änderung vornehmen und die Änderung auf allen vier Seiten widerspiegeln.

Verwendung des Layouts für die vier Seiten

Jetzt kann jede unserer vier Seiten eine Datei sein. Beginnen wir jedoch einfach mit index.njk , die in CodePen-Projekten automatisch verarbeitet wird und bei jedem Speichern eine index.html -Datei erstellt.

Die index.njk-Datei
Beginnen Sie mit einer index.njk-Datei

Folgendes könnten wir in index.njk , um das Layout zu verwenden und einige Inhalte in diesem Block abzulegen:

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

Das wird uns eine voll funktionsfähige Homepage kaufen! Hübsch! Jede der vier Seiten kann genau dasselbe tun, aber unterschiedliche Inhalte in den Block einfügen, und wir haben selbst eine kleine vierseitige Website, die einfach zu verwalten ist.

Kompilierte index.html
Die Datei index.njk wird in index.html kompiliert

Fürs Protokoll, ich bin mir nicht sicher, ob ich diese kleinen Teile, die wir wiederverwenden, als Komponenten bezeichnen würde. Wir sind einfach nur effizient und teilen ein Layout in Stücke auf. Ich stelle mir eine Komponente eher wie einen wiederverwendbaren Block vor, der Daten akzeptiert und mit diesen Daten eine eindeutige Version von sich selbst ausgibt. Wir werden dazu kommen.

Aktive Navigation machen

Nun, da wir einen identischen HTML-Abschnitt auf vier Seiten wiederholt haben, ist es möglich, eindeutiges CSS auf einzelne Navigationselemente anzuwenden, um die aktuelle Seite zu identifizieren? Wir könnten mit JavaScript und einem Blick auf window.location und dergleichen, aber wir können dies ohne JavaScript tun. Der Trick besteht darin, dem <body> eine class zuzuweisen, die für jede Seite eindeutig ist, und diese im CSS zu verwenden.

In unserer _layout.njk wir den Body einen Klassennamen als Variable ausgeben:

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

Bevor wir dieses Layout dann auf einer einzelnen Seite aufrufen, setzen wir diese Variable:

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

Nehmen wir an, unsere Navigation war wie folgt strukturiert

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

Jetzt können wir auf diesen Link abzielen und nach Bedarf ein spezielles Styling anwenden, indem wir Folgendes tun:

 body.home .nav-home a, body.services .nav-services a { /* continue matching classes for all pages... */ /* unique active state styling */ } 
Stil des aktiven Zustands bei der Navigation
Navigationslinks mit einer aktiven Klasse gestalten.

Oh, und diese Symbole? Das sind nur einzelne .svg Dateien, die ich in einen Ordner gelegt und wie eingefügt habe

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

Und das erlaubt mir, sie wie folgt zu stylen:

 svg { fill: white; }

Angenommen, die SVG-Elemente darin haben bereits keine fill .

Verfassen von Inhalten in Markdown

Die Homepage meiner Microsite hat einen großen Inhaltsblock. Ich könnte das sicherlich in HTML selbst schreiben und pflegen, aber manchmal ist es nett, so etwas Markdown zu überlassen. Markdown fühlt sich beim Schreiben sauberer an und ist vielleicht etwas einfacher anzusehen, wenn es sich um viele Kopien handelt.

Dies ist in CodePen Projects sehr einfach. Ich habe eine Datei mit der Endung .md erstellt, die automatisch in HTML verarbeitet wird, und diese dann in die Datei index.njk .

Markdown kompiliert in HTML auf CodePen Projects
Dateien in Markdown werden in CodePen-Projekten in HTML kompiliert.
 {% block content %} <main class="centered-text-column"> {% include "content/about.html" %} </main> {% endblock %}

Bauen von tatsächlichen Komponenten

Betrachten wir Komponenten als wiederholbare Module, die Daten übergeben, um sich selbst zu erstellen. In Frameworks wie Vue würden Sie mit einzelnen Dateikomponenten arbeiten, die isolierte Teile von vorlagenbasiertem HTML, bereichsbezogenem CSS und komponentenspezifischem JavaScript sind. Das ist super cool, aber unsere Microsite braucht nichts so Ausgefallenes.

Wir müssen einige „Karten“ basierend auf einer einfachen Vorlage erstellen, damit wir Dinge wie diese erstellen können:

Komponenten im Kartenstil
Wiederholbare Komponenten mit Vorlagen erstellen

Das Erstellen einer wiederholbaren Komponente wie der in Nunjucks beinhaltet die Verwendung sogenannter Makros. Makros sind herrlich einfach. Sie sind so, als ob HTML Funktionen hätte !

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

Dann rufen Sie es nach Bedarf auf:

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

Die ganze Idee hier ist, Daten und Markup zu trennen . Dies gibt uns einige ziemlich klare und greifbare Vorteile:

  1. Wenn wir eine Änderung am HTML vornehmen müssen, können wir es im Makro ändern und es wird überall dort geändert, wo dieses Makro verwendet wird.
  2. Die Daten sind nicht im Markup verheddert
  3. Die Daten könnten von überall her kommen! Wir codieren die Daten direkt in Aufrufe der Makros, wie wir es oben getan haben. Oder wir könnten auf einige JSON-Daten verweisen und sie durchlaufen. Ich bin sicher, Sie könnten sich sogar ein Setup vorstellen, in dem diese JSON-Daten von einer Art Headless-CMS, Build-Prozess, serverloser Funktion, Cron-Job oder was auch immer stammen.

Jetzt haben wir diese wiederholbaren Karten, die Daten und Markup kombinieren, genau das, was wir brauchen:

Daten und Markup für die Komponente werden getrennt gehalten
HTML wird im Makro gesteuert, während Daten von überall her kommen können

Machen Sie so viele Komponenten, wie Sie möchten

Sie können diese Idee nehmen und mit ihr laufen. Stellen Sie sich zum Beispiel vor, dass Bootstrap im Wesentlichen ein Bündel von CSS ist, dem Sie HTML-Muster zur Verwendung folgen. Sie könnten jedes dieser Muster zu einem Makro machen und es nach Bedarf aufrufen, wodurch das Framework im Wesentlichen in Komponenten unterteilt wird.

Sie können Komponenten verschachteln, wenn Sie möchten, und eine Art atomare Designphilosophie annehmen. Nunjucks bietet auch Logik, was bedeutet, dass Sie bedingte Komponenten und Variationen erstellen können, indem Sie einfach verschiedene Daten übergeben.

In der einfachen Website, die ich erstellt habe, habe ich ein anderes Makro für den Ideenbereich der Website erstellt, da es etwas andere Daten und ein etwas anderes Kartendesign beinhaltete.

Kartenkomponenten im Abschnitt „Ideen“.
Es können beliebig viele Komponenten erstellt werden

Ein kurzer Fall gegen statische Seiten

Ich könnte argumentieren, dass die meisten Websites von einer komponentenbasierten Architektur profitieren, aber nur einige Websites sind geeignet, statisch zu sein. Ich arbeite an vielen Websites, bei denen es angemessen und nützlich ist, Back-End-Sprachen zu haben.

Eine meiner Seiten, CSS-Tricks, hat Dinge wie eine Benutzeranmeldung mit einem etwas komplexen Berechtigungssystem: Foren, Kommentare, eCommerce. Obwohl nichts davon die Idee, statisch zu arbeiten, vollständig aufhält, bin ich oft froh, dass ich eine Datenbank und Back-End-Sprachen habe, mit denen ich arbeiten kann. Es hilft mir, das zu bauen, was ich brauche, und hält die Dinge unter einem Dach.

Gehen Sie hinaus und umarmen Sie das statische Leben!

Denken Sie daran, dass einer der Vorteile des Erstellens, wie wir es in diesem Artikel gemacht haben, darin besteht, dass das Endergebnis nur ein Haufen statischer Dateien ist. Einfach zu hosten, schnell und sicher. Dennoch mussten wir nicht auf eine entwicklerfreundliche Arbeitsweise verzichten. Diese Website kann in Zukunft einfach aktualisiert und ergänzt werden.

  • Das letzte Projekt ist eine Microsite namens The Power of Serverless für Front-End-Entwickler (https://thepowerofserverless.info/).
  • Statisches Dateihosting ist, wenn Sie mich fragen, ein Teil der serverlosen Bewegung.
  • Sie können den gesamten Code direkt auf CodePen sehen (und sogar eine Kopie für sich selbst forken). Es wird vollständig auf CodePen mithilfe von CodePen Projects erstellt, gewartet und gehostet.
  • CodePen Projects behandelt all die Nunjucks-Sachen, über die wir hier gesprochen haben, und auch Dinge wie Sass-Verarbeitung und Bildhosting, die ich für die Website genutzt habe. Sie könnten dasselbe beispielsweise mit einem Gulp- oder Grunt-basierten Build-Prozess lokal replizieren. Hier ist ein solches Boilerplate-Projekt, das Sie auf den Weg bringen könnten.