Using Trello as a Super Simple CMS

Avatar of Phil Hawksworth
Phil Hawksworth am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Manchmal benötigen unsere Websites ein kleines bisschen Content Management. Nicht immer. Nicht viel. Aber ein bisschen. Der CMS-Markt ist florierend mit erschwinglichen, zugänglichen Produkten, sodass wir keine Optionen vermissen. Glücklicherweise ist das eine ganz andere Welt als die, die früher Unternehmen dazu zwang, ein Vermögen von einer Milliarde-und-eins Dollar (keine exakte Kostenangabe: Ich habe auf die nächste Milliarde aufgerundet) für eine all-singende, all-tanzende, all-integrierende, all-personalisierende, Big-Enterprise-zertifizierte™ CMS-Plattform auszugeben.

Manchmal ist es jedoch schön, ein wirklich einfaches Tool zu verwenden, mit dem jeder, der Inhalte auf der Website aktualisiert, bereits vertraut ist, anstatt sich mit einem neuen CMS auseinandersetzen zu müssen. 

Ich mag Trello sehr für die Verwaltung von Ideen und Aufgaben. Und es hat eine API. Warum nicht als Content-Quelle für eine Website verwenden? Ich meine, hey, wenn wir das mit Google Sheets machen können, was hindert uns dann daran, andere Dinge auszuprobieren?

Hallo, Trello

Hier ist eine einfache Seite zum Erkunden. Sie bezieht ihre Inhalte von diesem Trello-Board und diese Inhalte werden in Abschnitten angezeigt. Jeder Abschnitt wird durch den Titel und die Beschreibungsfelder einer Karte in unserem Trello-Board gefüllt.

Two webpages side-by-side. The left is a Trello board with a bright pink background. The right is a screenshot of the build website using Trello data.

Trello verwendet Markdown, was hier praktisch ist. Jeder, der Inhalte in einer Trello-Karte bearbeitet, kann grundlegende Textformatierungen anwenden und derselbe Markdown-Fluss fließt in die Website ein und wird durch einen Build-Prozess in HTML umgewandelt.

Bausteine

Ich bin ein großer Fan dieses Modells, einen Build auszuführen, der Inhalte aus verschiedenen Feeds und Quellen abruft und sie dann mit einer Vorlage zusammenführt, um das HTML einer Website zu generieren. Es entkoppelt die Darstellung von der Verwaltung des Inhalts (daher der Begriff "entkoppelt" in populären modernen CMS-Produkten). Und es bedeutet, dass wir die Freiheit haben, die Website genau so zu gestalten, wie wir wollen, mit all den schicken Tricks und Techniken, die wir hier auf CSS-Tricks gelernt haben.

Diagram showing the flow of data, going from Trello as JSON to Build where the data and the template are coupled, then finally, to the front end.

Da wir die Inhalte zur Build-Zeit abrufen, müssen wir uns keine Gedanken über Nutzungslimits oder die Leistung unserer Datenquellen machen, wenn unsere Websites populär werden und viel Traffic generieren. Und warum sollten sie das nicht? Schauen Sie, wie schön wir sie gemacht haben!

Ich will spielen!

In Ordnung. Sie können eine Kopie des Codes dieser Website herunterladen und nach Herzenslust damit herumspielen. Diese Version enthält Informationen darüber, wie Sie Ihr eigenes Trello-Board erstellen und es als Content-Quelle für den Build verwenden können.

Wenn Sie zuerst durchgehen möchten, wie das funktioniert, anstatt sich selbst hineinzustürzen, lesen Sie weiter.

Die API entdecken

Trello hat eine gut dokumentierte API und eine Reihe von Entwicklerressourcen. Es gibt auch ein praktisches Node-Modul, um die Aufgabe der Authentifizierung und Interaktion mit der API zu vereinfachen. Sie können die API aber auch erkunden, indem Sie mit den URLs herumspielen, während Sie Ihre Trello-Boards durchsuchen. 

Zum Beispiel ist die URL für das obige Trello-Board

https://trello.com/b/Zzc0USwZ/hellotrello

Wenn wir dieser URL .json hinzufügen, zeigt Trello uns die Inhalte als JSON dargestellt. Schauen Sie mal.

Wir können diese Technik verwenden, um die zugrunde liegenden Daten in ganz Trello zu untersuchen. Hier ist die URL für eine bestimmte Karte

https://trello.com/c/YVxlSEzy/4-sections-from-cards

Wenn wir diesen kleinen Trick anwenden und .json zur URL hinzufügen, sehen wir die Daten, die diese Karte beschreiben

Wir werden interessante Dinge finden – eindeutige IDs für das Board, die Liste und die Karte. Wir können den Inhalt der Karte und viele Metadaten sehen.

Ich liebe es, das zu tun! Schauen Sie all die schönen Daten an! Wie sollen wir sie verwenden?

Entscheiden, wie ein Board verwendet wird

Für dieses Beispiel nehmen wir an, wir haben eine Website mit nur einer Seite mit verwaltbaren Inhalten. Eine Liste oder Spalte in unserem Board wäre ideal, um die Abschnitte auf dieser Seite zu steuern. Ein Redakteur könnte ihnen Titel und Inhalt geben und sie per Drag & Drop in die gewünschte Reihenfolge bringen.

Wir benötigen die ID der Liste, damit wir sie über die API abrufen können. Glücklicherweise haben wir bereits gesehen, wie wir das herausfinden können – schauen Sie sich die Daten für eine der Karten in der betreffenden Liste an. Jede hat eine Eigenschaft idBoard. Bingo!

Die Website generieren

Der Plan ist, die Daten von Trello abzurufen und sie auf einige Vorlagen anzuwenden, um unsere Website zu füllen. Die meisten Static Site Generatoren (SSG) würden die Aufgabe erfüllen. Dafür sind sie gut geeignet. Ich werde Eleventy verwenden, weil ich denke, dass es die einfachsten Konzepte zum Verstehen hat. Außerdem ist es sehr effizient darin, Daten abzurufen und mit Nunjucks (einer beliebten Vorlagensprache) sauberes HTML zu generieren.

Wir möchten in unserer Vorlage einen Ausdruck verwenden können, der für jedes Element in einem JavaScript-Objekt namens trello ein section-Element ausgibt

<!-- index.njk -->
{% for card in trello %}
<section>
  <h2>{{ card.name }}</h2>
  <div>
    {% markdown %}
      {{- card.desc | safe }}
    {% endmarkdown %}
  </div>
</section>
{% endfor %}

Abrufen der Daten für den Build

Eine beliebte Technik bei Jamstack-Websites wie dieser ist, einen Build mit Gulp, Grunt oder [aktuellster neuer Build-Script-Hype hier einfügen] auszuführen, der Daten aus verschiedenen APIs und Feeds abruft, die Daten in einem geeigneten Format für den SSG speichert und dann den SSG ausführt, um das HTML zu generieren. Das funktioniert recht gut.

Eleventy vereinfacht die Dinge hier, indem es die Ausführung von JavaScript in seinen Datendateien unterstützt. Mit anderen Worten, anstatt nur gespeicherte Daten als JSON oder YAML zu nutzen, kann es alles verwenden, was von JavaScript zurückgegeben wird. Das öffnet die Tür, direkte Anfragen an APIs zu stellen, wenn der Eleventy-Build läuft. Wir benötigen keinen separaten Build-Schritt, um zuerst Daten abzurufen. Eleventy erledigt das für uns.

Nutzen wir das, um die Daten für unser trello-Objekt in den Vorlagen zu erhalten.

Wir könnten den Trello Node Client verwenden, um die API abzufragen, aber wie sich herausstellt, sind alle Daten, die wir wollen, direkt im JSON des Boards enthalten. Alles! In einer Anfrage! Wir können es einfach auf einmal abrufen!

// trello.js
module.exports = () => {
  const TRELLO_JSON_URL='https://trello.com/b/Zzc0USwZ/hellotrello.json';

  // Use node-fetch to get the JSON data about this board
  const fetch = require('node-fetch');
  return fetch(TRELLO_JSON_URL)
    .then(res => res.json())
    .then(json => console.log(json));
};

Allerdings wollen wir nicht alle Daten von diesem Board anzeigen. Es enthält Karten in anderen Listen, Karten, die geschlossen und gelöscht wurden, und so weiter. Aber wir können die Karten filtern, um nur die interessanten einzuschließen, dank JavaScript's filter-Methode.

// trello.js
module.exports = () => {
   const TRELLO_JSON_URL='https://trello.com/b/Zzc0USwZ/hellotrello.json'
   const TRELLO_LIST_ID='5e98325d6d6bd120f2b7395f',
 
   // Use node-fetch to get the JSON data about this board
   const fetch = require('node-fetch');
   return fetch(TRELLO_JSON_URL)
   .then(res => res.json())
   .then(json => {
 
     // Just focus on the cards which are in the list we want
     // and do not have a closed status
     let contentCards = json.cards.filter(card => {
       return card.idList == TRELLO_LIST_ID && !card.closed;
     });
 
     return contentCards;
 });
};

Das war's! Wenn das in einer Datei namens trello.js im Datenverzeichnis von Eleventy gespeichert ist, haben wir diese Daten bereit zur Verwendung in unseren Vorlagen in einem Objekt namens trello

Fertig! 🎉

Aber wir können es noch besser machen. Lassen Sie uns auch angehängte Bilder behandeln und eine Möglichkeit hinzufügen, Inhalte zur Überprüfung vorzubereiten, bevor sie live gehen.

Bildanhänge

Es ist möglich, Dateien an Karten in Trello anzuhängen. Wenn Sie ein Bild anhängen, erscheint es direkt dort in der Karte mit der Quell-URL des Assets, die in den Daten beschrieben ist. Das können wir nutzen!

Wenn eine Karte einen Bildanhang hat, möchten wir die Quell-URL abrufen und sie als Bild-Tag zu dem hinzufügen, was unsere Vorlage zur Build-Zeit in die Seite einfügt. Das bedeutet, den Markdown für ein Bild zum Markdown in der Beschreibungs-Eigenschaft unseres JSON (card.desc) hinzuzufügen. 

Dann können wir Eleventy das für uns zusammen mit allem anderen in HTML umwandeln lassen. Dieser Code sucht nach Karten in unserem JSON und formatiert die Daten in die Form, die wir benötigen.

// trello.js

// If a card has an attachment, add it as an image 
// in the description markdown
contentCards.forEach(card => {
  if(card.attachments.length) {
    card.desc = card.desc + `\n![${card.name}](${card.attachments[0].url} '${card.name}')`;
  }
});

Jetzt können wir auch Bilder in unserem Content verschieben. Praktisch!

Inhalte bereitstellen

Fügen wir noch eine kleine Raffinesse hinzu, wie wir Trello zur Verwaltung der Website-Inhalte nutzen können.

Es gibt einige Möglichkeiten, wie wir Inhalte vor der Veröffentlichung für die Welt testen könnten. Unser Trello-Board könnte eine Liste für Staging und eine Liste für Produktionsinhalte haben. Aber das würde es schwierig machen, zu visualisieren, wie neue Inhalte neben den bereits veröffentlichten leben.

Eine bessere Idee wäre es, die Trello-Labels zu verwenden, um anzuzeigen, welche Karten live veröffentlicht werden und welche nur auf einer gestagten Version der Website enthalten sein sollen. Das gibt uns einen schönen Workflow. Wir können mehr Inhalte hinzufügen, indem wir eine neue Karte am richtigen Ort erstellen. Kennzeichnen Sie sie mit "stage" und filtern Sie sie aus den Karten heraus, die auf unserem Produktions-Branch erscheinen. 

Screenshot of the Trello board with a bright pink background. It has cards in a column called Published.
Label-Hinweise in Trello, die zeigen, welche Inhalte gestaged und welche live sind

Etwas mehr Filterung unseres JavaScript-Objekts ist erforderlich

// trello.js

// only include cards labelled with "live" or with
// the name of the branch we are in
contentCards = contentCards.filter(card => {
  return card.labels.filter(label => (
    label.name.toLowerCase() == 'live' ||
    label.name.toLowerCase() == BRANCH
   )).length;
 });

Wir möchten, dass die mit 'live' gekennzeichneten Inhalte auf jeder Version des Builds, ob gestaged oder nicht, angezeigt werden. Zusätzlich werden wir uns Karten ansehen, die ein Label haben, das mit einer Variablen namens "BRANCH" übereinstimmt.

Warum? Was ist das?

Hier werden wir raffiniert! Ich habe mich entschieden, diese Website auf Netlify zu hosten (Haftungsausschluss: Ich arbeite dort). Das bedeutet, dass ich den Build von Netlify's CI/CD-Umgebung ausführen kann. Dies stellt die Website bei jeder Änderung seines Git-Repositorys neu bereit und bietet Zugriff auf ein paar weitere Dinge, die für diese Website wirklich praktisch sind. 

Eines davon sind Branch-Deployments. Wenn Sie eine neue Umgebung für eine Website wünschen, können Sie eine erstellen, indem Sie einen neuen Branch im Git-Repository erstellen. Der Build wird in diesem Kontext ausgeführt, und Ihre Website wird auf einer Subdomain veröffentlicht, die den Branch-Namen enthält. So wie hier.

Schauen Sie sich das an und Sie werden alle Karten aus unserer Liste sehen, einschließlich derjenigen mit dem orangefarbenen "stage"-Label. Wir haben sie in diesen Build aufgenommen, weil ihr Label dem Branch-Namen für den Build-Kontext entsprach. BRANCH war eine Umgebungsvariable, die den Branch enthielt, in dem der Build ausgeführt wurde.

label.name.toLowerCase() == BRANCH

Theoretisch könnten wir so viele Branches und Labels erstellen, wie wir möchten, und alle Arten von Staging- und Testumgebungen haben. Bereit, etwas von "stage" auf "live" zu befördern? Tauschen Sie die Labels und Sie sind fertig!

Aber wie aktualisiert es sich?

Der zweite Vorteil, den wir durch die Ausführung des Website-Builds in einer CI/CD wie Netlify erhalten, ist, dass wir einen Build ausführen können, wann immer wir wollen. Netlify ermöglicht es uns, Build Hooks zu erstellen. Das sind Webhooks, die eine neue Bereitstellung auslösen, wenn Sie einen HTTP POST an sie senden.

Wenn Trello auch Webhooks unterstützt, dann könnten wir diese Dienste miteinander verbinden und die Website automatisch aktualisieren, sobald sich das Trello-Board ändert. Und raten Sie mal... tun sie das! Hurra!

Um einen Netlify-Build-Hook zu erstellen, müssen Sie das Admin-Panel Ihrer Website besuchen. (Sie können diese Demo-Website mit wenigen Klicks in einer neuen Netlify-Website einrichten, wenn Sie es ausprobieren möchten.)

Screenshot of the netlify build hooks screen with options to add a build hook and generate a public deploy key.
Erstellung eines Netlify Build Hooks

Jetzt, mit einer neuen Build-Hook-URL ausgestattet, müssen wir einen neuen Trello-Webhook registrieren, der ihn aufruft, wenn sich Inhalte ändern. Die Methode zur Erstellung von Webhooks in Trello ist über die Trello API

Das Repository für diese Website enthält ein kleines Dienstprogramm, um die Trello API aufzurufen und den Webhook für Sie zu erstellen. Sie benötigen jedoch einen Trello-Entwickler-Token und einen Schlüssel. Glücklicherweise ist es einfach, diese kostenlos zu erstellen, indem Sie das Trello Developer Portal besuchen und den Anweisungen unter "Authorizing a client" folgen.

Haben Sie sie? Großartig! Wenn Sie sie in einer .env-Datei in Ihrem Projekt speichern, können Sie diesen Befehl ausführen, um den Trello-Webhook einzurichten

npm run hook --url https://api.netlify.com/build_hooks/XXXXX

Und damit haben wir einen schönen kleinen Workflow für die Verwaltung von Inhalten auf einer einfachen Website erstellt. Wir können unser Frontend so gestalten, wie wir es möchten, und Änderungen an den Inhalten auf einem Trello-Board vornehmen, das die Website automatisch aktualisiert, sobald Änderungen vorgenommen werden.

Könnte ich das wirklich benutzen?

Dies ist ein simplistisches Beispiel. Das ist beabsichtigt. Ich wollte wirklich die Konzepte der Entkopplung und der Nutzung der API eines externen Dienstes zur Steuerung der Inhalte einer Website demonstrieren.

Dies wird kein vollwertiges entkoppeltes CMS für komplexere Projekte ersetzen. Aber die Prinzipien sind für komplexere Websites durchaus anwendbar.

Dieses Modell könnte jedoch eine großartige Ergänzung für die Arten von Websites sein, die wir für Unternehmen wie unabhängige Geschäfte, Bars und Restaurants sehen. Stellen Sie sich ein Trello-Board vor, das eine Liste zur Verwaltung der Startseite eines Restaurants und eine weitere zur Verwaltung der Menüpunkte hat. Sehr zugänglich für das Restaurantpersonal zur Verwaltung und viel besser, als jedes Mal ein neues PDF der Speisekarte hochzuladen, wenn sie sich ändert.

Bereit, ein Beispiel zu erkunden und mit Ihrem eigenen Board und Content zu experimentieren? Probieren Sie das hier aus