Im letzten Artikel haben wir gelernt, was bei der Planung einer Community-basierten Website zu beachten ist. Wir haben gesehen, wie viele Überlegungen erforderlich sind, um Benutzereinreichungen entgegenzunehmen, anhand meiner Erfahrungen beim Aufbau von Style Stage.
Nachdem wir die Planung behandelt haben, kommen wir nun zum Code! Gemeinsam entwickeln wir eine Eleventy-Einrichtung, die Sie als Ausgangspunkt für Ihre eigene Community- (oder persönliche) Website verwenden können.
Artikelserie
- Vorbereitung auf Beiträge
- Aufbau der Website (Sie sind hier!)
Dieser Artikel behandelt
- Wie man Eleventy initialisiert und nützliche Entwicklungs- und Build-Skripte erstellt
- Empfohlene Anpassungen der Einrichtung
- Wie man benutzerdefinierte Daten definiert und mehrere Datenquellen kombiniert
- Erstellung von Layouts mit Nunjucks und Eleventy-Layout-Chaining
- Bereitstellung auf Netlify
Die Vision
Nehmen wir an, wir möchten es Leuten ermöglichen, ihre Hunde und Katzen einzureichen und sie in Niedlichkeitswettbewerben gegeneinander antreten zu lassen.

Wir werden in diesem Artikel nicht auf Benutzerabstimmungen eingehen. Das wäre sehr cool (und mit serverlosen Funktionen absolut möglich), aber unser Fokus liegt auf den Haustiereinreichungen selbst. Mit anderen Worten, Benutzer können Profildetails für ihre Katzen und Hunde einreichen. Wir werden diese Einreichungen verwenden, um einen wöchentlichen Wettbewerb zu erstellen, bei dem eine zufällige Katze gegen einen zufälligen Hund auf der Startseite antritt, um darüber zu streiten, wer am *wuffigsten* ist (oder schnurriger, wenn Sie bevorzugen).
Legen wir Eleventy auf!
Wir beginnen, indem wir ein neues Projekt initialisieren, indem wir npm init in einem beliebigen Verzeichnis ausführen, und dann Eleventy darin installieren mit
npm install @11ty/eleventy
Obwohl es völlig optional ist, öffne ich gerne die package-json-Datei, die dem Verzeichnis hinzugefügt wird, und ersetze den scripts-Abschnitt damit
"scripts": {
"develop": "eleventy --serve",
"build": "eleventy"
},
Dies ermöglicht es uns, Eleventy in einer Entwicklungsumgebung (npm run develop) zu starten, die Browsersync-Hot-Reloading für die lokale Entwicklung beinhaltet. Außerdem wird ein Befehl hinzugefügt, der unsere Arbeit kompiliert und erstellt (npm run build) für die Bereitstellung auf einem Produktionsserver.
Wenn Sie denken: „npm *was*?“, dann rufen wir Node auf (was Eleventy benötigt). Die hier genannten Befehle sind für die Ausführung in Ihrem bevorzugten Terminal gedacht, das ein zusätzliches Programm sein kann oder in Ihren Code-Editor integriert ist, wie z. B. in VS Code.
Wir benötigen ein weiteres npm-Paket, fast-glob, das wir später für die Kombination von Daten verwenden werden. Installieren wir es gleich jetzt
npm install --save-dev fast-glob.
Konfigurieren wir unser Verzeichnis
Eleventy erlaubt die Anpassung des Eingabeverzeichnisses (wo wir arbeiten) und des Ausgabeverzeichnisses (wo unsere erstellte Arbeit hinkommt), um etwas zusätzliche Organisation zu bieten.
Um dies zu konfigurieren, erstellen wir die Datei eleventy.js im Stammverzeichnis des Projekts. Dann teilen wir Eleventy mit, wohin unsere Eingabe- und Ausgabeverzeichnisse gehen sollen. In diesem Fall verwenden wir ein Verzeichnis src für die Eingabe und ein Verzeichnis public für die Ausgabe.
module.exports = function (eleventyConfig) {
return {
dir: {
input: "src",
output: "public"
},
};
};
Als nächstes erstellen wir ein Verzeichnis namens pets, in dem wir die Haustierdaten speichern, die wir von Benutzereinreichungen erhalten. Wir können dieses Verzeichnis sogar etwas weiter unterteilen, um Merge-Konflikte zu reduzieren und Katzen- von Hundedaten mit den Unterverzeichnissen cat und dog klar zu unterscheiden.
pets/
cats/
dogs/
Wie sehen die Daten aus? Benutzer senden eine JSON-Datei, die diesem Schema folgt, wobei jede Eigenschaft ein Datenpunkt über das Haustier ist
{
"name": "",
"petColor": "",
"favoriteFood": "",
"favoriteToy": "",
"photoURL": "",
"ownerName": "",
"ownerTwitter": ""
}
Um den Einreichungsprozess für Benutzer kristallklar zu gestalten, können wir eine Datei CONTRIBUTING.md im Stammverzeichnis des Projekts erstellen und die Richtlinien für Einreichungen aufschreiben. GitHub nimmt den Inhalt dieser Datei und zeigt ihn im Repository an. Auf diese Weise können wir Anleitungen zu diesem Schema geben, wie z. B. den Hinweis, dass favoriteFood, favoriteToy und ownerTwitte optionale Felder sind.
Eine Datei README.md wäre genauso gut, wenn Sie diesen Weg bevorzugen. Es ist einfach schön, dass es eine Standarddatei gibt, die speziell für Beiträge gedacht ist.
Beachten Sie, dass photoURL eine dieser Eigenschaften ist. Wir hätten daraus eine Datei machen können, aber aus Gründen der Sicherheit und der Hostingkosten bitten wir stattdessen um eine URL. Möglicherweise entscheiden Sie sich, tatsächliche Dateien anzunehmen, und das ist völlig in Ordnung.
Arbeiten wir mit Daten
Als Nächstes müssen wir ein kombiniertes Daten-Array aus den einzelnen Katzen- und Hundedateien erstellen. Dies ermöglicht es uns, sie zu durchlaufen, um Website-Seiten zu erstellen und zufällige Katzen- und Hundeeinreichungen für die wöchentlichen Wettbewerbe auszuwählen.
Eleventy erlaubt Node module.exports innerhalb des Verzeichnisses _data. Das bedeutet, wir können eine Funktion erstellen, die alle Katzendateien findet und eine andere, die alle Hundedateien findet, und dann Arrays aus jedem Set erstellt. Es ist, als würde man jede Katzendatei nehmen und sie zu einem Datensatz in einer einzigen JavaScript-Datei zusammenführen, und dann dasselbe mit Hunden tun.
Der Dateiname, der in _data verwendet wird, wird zur Variablen, die diesen Datensatz speichert. Daher fügen wir dort Dateien für Katzen und Hunde hinzu
_data/
cats.js
dogs.js
Die Funktionen in jeder Datei werden nahezu identisch sein – wir tauschen lediglich Instanzen von „Katze“ gegen „Hund“ zwischen den beiden aus. Hier ist die Funktion für Katzen:
const fastglob = require("fast-glob");
const fs = require("fs");
module.exports = async () => {
// Create a "glob" of all cat json files
const catFiles = await fastglob("./src/pets/cats/*.json", {
caseSensitiveMatch: false,
});
// Loop through those files and add their content to our `cats` Set
let cats = new Set();
for (let cat of catFiles) {
const catData = JSON.parse(fs.readFileSync(cat));
cats.add(catData);
}
// Return the cats Set of objects within an array
return [...cats];
};
Sieht das beängstigend aus? Keine Angst! Ich schreibe auch nicht regelmäßig Node, und es ist kein erforderlicher Schritt für weniger komplexe Eleventy-Websites. Wenn wir stattdessen gewählt hätten, dass Mitwirkende zu einer ständig wachsenden einzelnen JSON-Datei mit _data beitragen, dann wäre dieser Kombinationsschritt gar nicht erst notwendig. Der Hauptgrund für diesen Schritt ist wiederum die Reduzierung von Merge-Konflikten, indem individuelle Mitwirkendendateien ermöglicht werden. Das ist auch der Grund, warum wir fast-glob in den Mix aufgenommen haben.
Ausgeben wir die Daten
Dies ist ein guter Zeitpunkt, um mit der Eingabe von Daten in die Vorlagen für unsere Benutzeroberfläche zu beginnen. Lassen Sie uns sogar ein paar JSON-Dateien in die Verzeichnisse pets/cats und pets/dogs einfügen, die Daten für die Eigenschaften enthalten, damit wir sofort etwas zum Arbeiten und Testen haben.
Wir können unsere erste Eleventy-Seite hinzufügen, indem wir eine Datei index.njk im src-Verzeichnis erstellen. Dies wird zur Startseite, und es handelt sich um ein Nunjucks-Vorlagendateiformat.
Nunjucks ist eine von vielen Optionen zum Erstellen von Vorlagen mit Eleventy. Siehe die Dokumentation für eine vollständige Liste der Vorlagenoptionen.
Beginnen wir damit, unsere Daten zu durchlaufen und eine ungeordnete Liste sowohl für Katzen als auch für Hunde auszugeben
<ul>
<!-- Loop through cat data -->
{% for cat in cats %}
<li>
<a href="/cats/{{ cat.name | slug }}/">{{ cat.name }}</a>
</li>
{% endfor %}
</ul>
<ul>
<!-- Loop through dog data -->
{% for dog in dogs %}
<li>
<a href="/dogs/{{ dog.name | slug }}/">{{ dog.name }}</a>
</li>
{% endfor %}
</ul>
Zur Erinnerung: Die Referenz auf cats und dogs entspricht dem Dateinamen in _data. Innerhalb der Schleife können wir über die JSON-Schlüssel mit Punktnotation auf sie zugreifen, wie bei cat.name, das als Nunjucks-Vorlagenvariable mit doppelten geschweiften Klammern ausgegeben wird (z. B. {{ cat.name }}).
Erstellen wir Haustierprofilseiten
Neben Listen von Katzen und Hunden auf der Startseite (index.njk) möchten wir auch individuelle Profilseiten für jedes Haustier erstellen. Die Schleife deutete auf die Struktur hin, die wir dafür verwenden werden, nämlich [haustiertyp]/[name-slug].
Der empfohlene Weg, Seiten aus Daten zu erstellen, ist über das Eleventy-Konzept der Pagination, die das Aufteilen von Daten ermöglicht.
Wir werden die Dateien, die für die Pagination verantwortlich sind, im Stammverzeichnis von src erstellen, aber Sie könnten sie in einem benutzerdefinierten Verzeichnis verschachteln, solange es sich innerhalb von src befindet und von Eleventy erkannt werden kann.
src/
cats.njk
dogs.njk
Dann fügen wir unsere Pagination-Informationen als Front Matter hinzu, gezeigt für Katzen
---
pagination:
data: cats
alias: cat
size: 1
permalink: "/cats/{{ cat.name | slug }}/"
---
Der Wert data ist der Dateiname aus _data. Der Wert alias ist optional, wird aber verwendet, um auf ein einzelnes Element aus dem paginierten Array zu verweisen. size: 1 gibt an, dass wir eine Seite pro Datenelement erstellen.
Um die Seitenausgabe erfolgreich zu erstellen, müssen wir auch die gewünschte Permalink-Struktur angeben. Hier kommt der obige alias-Wert zum Einsatz, der auf den name-Schlüssel aus dem Datensatz zugreift. Dann verwenden wir einen integrierten Filter namens slug, der einen Zeichenkettenwert in eine URL-freundliche Zeichenkette umwandelt (Kleinschreibung und Umwandlung von Leerzeichen in Bindestriche usw.).
Lassen Sie uns überprüfen, was wir bisher haben
Jetzt ist es an der Zeit, Eleventy mit npm run develop zu starten. Dies startet den lokalen Server und zeigt Ihnen eine URL im Terminal an, die Sie zur Anzeige des Projekts verwenden können. Fehler beim Erstellen werden im Terminal angezeigt, falls vorhanden.
Solange alles erfolgreich war, erstellt Eleventy ein Verzeichnis public, das enthalten sollte
public/
cats/
cat1-name/index.html
cat2-name/index.html
dogs/
dog1-name/index.html
dog2-name/index.html
index.html
Und im Browser sollte die Indexseite eine verknüpfte Liste von Katzennamen und eine weitere von verknüpften Hundnamen anzeigen.
Fügen wir Daten zu Haustierprofilseiten hinzu
Jede der generierten Seiten für Katzen und Hunde ist derzeit leer. Wir haben Daten, die wir verwenden können, um sie zu füllen, also lassen Sie uns sie nutzen.
Eleventy erwartet ein Verzeichnis _includes, das Layout-Dateien („Vorlagen“) oder Vorlagenfragmente enthält, die in Layouts eingefügt werden.
Wir werden zwei Layouts erstellen
src/
_includes/
base.njk
pets.njk
Der Inhalt von base.njk wird eine HTML-Grundstruktur sein. Das <body>-Element darin wird ein spezielles Vorlagentag enthalten: {{ content | safe }}, wo übergebene Inhalte in der Vorlage gerendert werden, wobei „safe“ bedeutet, dass beliebige HTML-Inhalte gerendert werden können, anstatt sie zu kodieren.
Dann können wir die Startseite, index.md, dem base.njk-Layout zuweisen, indem wir Folgendes als Front Matter hinzufügen. Dies sollte das Erste in index.md sein, einschließlich der Striche
---
layout: base.njk
---
Wenn Sie sich den kompilierten HTML-Code im Verzeichnis public ansehen, sehen Sie, dass die von uns erstellten Schleifen für Katzen und Hunde nun innerhalb des <body> des base.njk-Layouts ausgegeben werden.
Als Nächstes fügen wir das *gleiche* Front Matter zu pets.njk hinzu, um zu definieren, dass es ebenfalls das base.njk-Layout verwendet, um das Eleventy-Konzept des Layout-Chaining zu nutzen. Auf diese Weise werden die Inhalte, die wir in pets.njk platzieren, von der HTML-Grundstruktur in base.njk umschlossen, sodass wir diese HTML jedes Mal nicht neu schreiben müssen.
Um die einzelne pets.njk-Vorlage zum Rendern von Katzen- und Hundeprofil-Daten zu verwenden, verwenden wir eine der neuesten Eleventy-Funktionen, die Computed Data. Dies ermöglicht es uns, Werte aus den Katzen- und Hundedaten denselben Vorlagenvariablen zuzuweisen, anstatt if-Anweisungen oder zwei separaten Vorlagen (eine für Katzen und eine für Hunde) zu verwenden. Der Vorteil ist, wieder einmal, die Vermeidung von Redundanz.
Hier ist das erforderliche Update in cats.njk, mit demselben Update, das in dogs.njk erforderlich ist (wobei cat durch dog ersetzt wird)
eleventyComputed:
title: "{{ cat.name }}"
petColor: "{{ cat.petColor }}"
favoriteFood: "{{ cat.favoriteFood }}"
favoriteToy: "{{ cat.favoriteToy }}"
photoURL: "{{ cat.photoURL }}"
ownerName: "{{ cat.ownerName }}"
ownerTwitter: "{{ cat.ownerTwitter }}"
Beachten Sie, dass eleventyComputed diesen Schlüssel für Front Matter-Arrays definiert und dann den Alias für den Zugriff auf Werte im cats-Datensatz verwendet. Nun können wir zum Beispiel einfach {{ title }} verwenden, um auf den Namen einer Katze *und* den Namen eines Hundes zuzugreifen, da die Vorlagenvariable jetzt dieselbe ist.
Wir können damit beginnen, den folgenden Code in pets.njk einzufügen, um je nach angezeigter Seite erfolgreich Katzen- oder Hundeprofil-Daten zu laden
<img src="{{ photoURL }}" />
<ul>
<li><strong>Name</strong>: {{ title }}</li>
<li><strong>Color</strong>: {{ petColor }}</li>
<li><strong>Favorite Food</strong>: {{ favoriteFood if favoriteFood else 'N/A' }}</li>
<li><strong>Favorite Toy</strong>: {{ favoriteToy if favoriteToy else 'N/A' }}</li>
{% if ownerTwitter %}
<li><strong>Owner</strong>: <a href="{{ ownerTwitter }}">{{ ownerName }}</a></li>
{% else %}
<li><strong>Owner</strong>: {{ ownerName }}</li>
{% endif %}
</ul>
Das Letzte, was wir brauchen, um dies alles zusammenzubinden, ist das Hinzufügen von layout: pets.njk zum Front Matter in sowohl cats.njk als auch dogs.njk.
Mit laufendem Eleventy können Sie jetzt eine einzelne Haustierseite besuchen und deren Profil sehen

Wir werden in diesem Artikel nicht auf Styling eingehen, aber Sie können sich das Beispielprojekt-Repository ansehen, um zu sehen, wie CSS integriert ist.
Stellen wir dies in Produktion!
Die Website ist nun funktionsfähig und kann in eine Hosting-Umgebung bereitgestellt werden!
Wie bereits empfohlen, ist Netlify eine ideale Wahl, insbesondere für eine Community-basierte Website, da sie bei jeder Zusammenführung einer Einreichung eine Bereitstellung auslösen und eine Vorschau der Einreichung anzeigen kann, bevor sie zur Überprüfung gesendet wird.
Wenn Sie sich für Netlify entscheiden, sollten Sie Ihre Website in ein GitHub-Repository pushen, das Sie bei der Hinzufügung einer Website zu Ihrem Netlify-Konto auswählen können. Wir werden Netlify anweisen, aus dem Verzeichnis public zu bedienen und npm run build auszuführen, wenn neue Änderungen in den Hauptzweig übernommen werden.
Die Beispielwebsite enthält eine Datei netlify.toml, die die Build-Details enthält und von Netlify im Repository automatisch erkannt wird, wodurch die Notwendigkeit entfällt, die Details im neuen Website-Flow zu definieren.
Nachdem die anfängliche Website hinzugefügt wurde, besuchen Sie Einstellungen → Build → Bereitstellen in Netlify. Wählen Sie unter Bereitstellungskontexte „Bearbeiten“ und aktualisieren Sie die Auswahl für „Bereitstellungsvorschauen“ auf „Alle Pull-Anfragen gegen Ihren Produktionszweig / Branch-Deployments-Zweige“. Nun wird für jede Pull-Anfrage eine Vorschau-URL generiert, wobei der Link direkt im Pull-Request-Überprüfungsbildschirm verfügbar ist.
Fangen wir an, Einreichungen anzunehmen!
Bevor wir loslegen und 100 $ einsammeln, ist es eine gute Idee, den ersten Beitrag noch einmal zu lesen und sicherzustellen, dass wir bereit sind, Benutzereinreichungen entgegenzunehmen. Zum Beispiel sollten wir Community Health Files zum Projekt hinzufügen, falls diese noch nicht hinzugefügt wurden. Das Wichtigste ist vielleicht, sicherzustellen, dass eine Branch-Schutzregel für den Hauptzweig eingerichtet ist. Das bedeutet, dass Ihre Genehmigung erforderlich ist, bevor eine Pull-Anfrage zusammengeführt wird.
Mitwirkende benötigen ein GitHub-Konto. Dies mag wie eine Hürde erscheinen, aber es reduziert die Anonymität. Abhängig von der Sensibilität des Inhalts oder der Zielgruppe kann dies tatsächlich dazu beitragen, Mitwirkende zu *prüfen* (verstehen Sie den Witz?).
Hier ist der Einreichungsprozess
- Forken Sie das Website-Repository.
- Klonen Sie den Fork auf einen lokalen Rechner *oder* verwenden Sie die GitHub-Weboberfläche für die restlichen Schritte.
- Erstellen Sie eine eindeutige .json-Datei in src/pets/cats oder src/pets/dogs, die die erforderlichen Daten enthält.
- Committen Sie die Änderungen, wenn sie auf einem Klon vorgenommen wurden, oder speichern Sie die Datei, wenn sie in der Weboberfläche bearbeitet wurde.
- Öffnen Sie eine Pull-Anfrage zurück zum Haupt-Repository.
- (Optional) Überprüfen Sie die Netlify-Bereitstellungsvorschau, um zu verifizieren, dass die Informationen wie erwartet angezeigt werden.
- Führen Sie die Änderungen zusammen.
- Netlify stellt das neue Haustier auf der Live-Website bereit.
Ein FAQ-Abschnitt ist ein guter Ort, um Mitwirkende darüber zu informieren, wie man Pull-Anfragen erstellt. Sie können ein Beispiel auf Style Stage ansehen.
Lassen Sie uns dies abschließen...
Was wir haben, ist eine voll funktionsfähige Website, die Benutzereinreichungen als Beiträge zum Projekt-Repository akzeptiert. Sie stellt diese Beiträge sogar automatisch bereit, wenn sie zusammengeführt werden!
Es gibt noch viele weitere Dinge, die wir mit einer Community-basierten Website, die mit Eleventy erstellt wurde, tun können. Zum Beispiel
- Markdown-Dateien können für den Inhalt eines E-Mail-Newsletters verwendet werden, der mit Buttondown versendet wird. Eleventy ermöglicht das Mischen von Markdown mit Nunjucks oder Liquid. So können Sie zum Beispiel eine Nunjucks-Schleife verwenden, um die neuesten fünf Haustiere als Links auszugeben, die in Markdown-Syntax ausgegeben werden und von Buttondown übernommen werden.
- Automatisch generierte Vorschau-Bilder für soziale Medien können für Link-Vorschauen in sozialen Netzwerken erstellt werden.
- Ein Kommentarsystem kann hinzugefügt werden.
- Netlify CMS Open Authoring kann verwendet werden, um Leuten die Erstellung von Einreichungen über eine Benutzeroberfläche zu ermöglichen. Sehen Sie sich Chris' großartige Zusammenfassung, wie es funktioniert, an.
Mein Meow vs. BowWow-Beispiel steht Ihnen zum Forken auf GitHub zur Verfügung. Sie können auch die Live-Vorschau anzeigen und ja, Sie können wirklich Ihr Haustier auf dieser albernen Website einreichen. 🙂
Viel Erfolg beim Aufbau einer gesunden und blühenden Community!
Artikelserie
- Vorbereitung auf Beiträge
- Aufbau der Website (Sie sind hier!)