Erinnern Sie sich an Tabletop.js? Wir haben es gerade erst vor Kurzem behandelt, in genau diesem Kontext: Erstellung von bearbeitbaren Websites. Es ist ein Werkzeug, das eine Google-Tabelle in eine API verwandelt, die Sie als Entwickler beim Erstellen einer Website für Daten abrufen können. Im letzten Artikel haben wir diese API clientseitig verwendet, was bedeutet, dass JavaScript bei jedem einzelnen Seitenaufruf ausgeführt werden musste, die URL für die Daten aufgerufen und die Seite erstellt wurde. Das mag unter Umständen in Ordnung sein, aber wir machen es noch besser. Wir rufen die API während des Build-Schritts auf, sodass der Inhalt direkt in das HTML integriert wird. Das wird weitaus schneller und resilienter sein.
Die Situation
Als Entwickler mussten Sie vielleicht mit Kunden zusammenarbeiten, die Sie mit endlosen Überarbeitungen von Inhalten belästigen, manchmal sogar Monate nach der Erstellung der Website. Das kann frustrierend sein, da es Sie immer wieder zurückwirft und Sie von produktiverer Arbeit abhält.
Wir werden ihnen die Schlüssel zur Aktualisierung von Inhalten selbst geben, indem wir ein Werkzeug verwenden, mit dem sie wahrscheinlich bereits vertraut sind: Google Sheets.
Ein neues Werkzeug
Im letzten Artikel haben wir das Konzept der Verwendung von Google Sheets mit Tabletop.js eingeführt. Jetzt führen wir ein neues Werkzeug für diese Party ein: Eleventy.
Wir werden Eleventy (einen statischen Site-Generator) verwenden, da wir möchten, dass die Website als reine statische Website gerendert wird, ohne die gesamte Funktionsweise der Website in den clientseitigen JavaScript zu versenden. Wir werden die Inhalte zur Build-Zeit aus der API abrufen und Eleventy eine minimierte index.html erstellen lassen, die wir auf den Server für die Produktionswebsite hochladen. Da es statisch ist, lädt die Seite schneller und ist aus Sicherheitsgründen besser.
Die Tabelle
Wir werden eine Demo verwenden, die ich erstellt habe, mit seinem Repository und Google Sheet, um zu demonstrieren, wie etwas Ähnliches in Ihren eigenen Projekten repliziert werden kann. Zuerst benötigen wir eine Google-Tabelle, die unser Datenspeicher sein wird.
Öffnen Sie eine neue Tabelle und geben Sie Ihre eigenen Werte in die Spalten ein genau wie meine. Die erste Zelle jeder Spalte ist die Referenz, die später in unserem JavaScript verwendet wird, und die zweite Zelle ist der tatsächliche Inhalt, der angezeigt wird.

Als Nächstes veröffentlichen wir die Daten im Web, indem wir auf Datei → Im Web veröffentlichen in der Menüleiste klicken.

Ein Link wird bereitgestellt, aber er ist technisch nutzlos für uns, daher können wir ihn ignorieren. Wichtig ist, dass die Tabelle (und ihre Daten) jetzt öffentlich zugänglich sind, damit wir sie für unsere App abrufen können.
Beachten Sie, dass wir die eindeutige ID des Blattes aus seiner URL benötigen werden, während wir fortfahren.
Node wird benötigt, um fortzufahren. Stellen Sie also sicher, dass dies installiert ist. Wenn Sie den Prozess der Installation aller Abhängigkeiten für diese Arbeit überspringen möchten, können Sie mein Repository forken oder herunterladen und Folgendes ausführen:
npm install
Führen Sie als Nächstes diesen Befehl aus – ich werde später erklären, warum er wichtig ist
npm run seed
Dann, um es lokal auszuführen
npm run dev
Okay, gehen wir zu src/site/_data/prod/sheet.js. Hier werden wir Daten aus der Google-Tabelle abrufen, sie in ein Objekt umwandeln, das wir leicht verwenden können, und schließlich das JavaScript-Objekt zurück in JSON-Format konvertieren. Das JSON wird lokal für die Entwicklung gespeichert, damit wir die API nicht jedes Mal aufrufen müssen.
Hier ist der Code, den wir dort haben wollen. Stellen Sie wieder sicher, dass Sie die Variable sheetID auf die eindeutige ID Ihres eigenen Blattes ändern.
module.exports = () => {
return new Promise((resolve, reject) => {
console.log(`Requesting content from ${googleSheetUrl}`);
axios.get(googleSheetUrl)
.then(response => {
// massage the data from the Google Sheets API into
// a shape that will more convenient for us in our SSG.
var data = {
"content": []
};
response.data.feed.entry.forEach(item => {
data.content.push({
"header": item.gsx$header.$t,
"header2": item.gsx$header2.$t,
"body": item.gsx$body.$t,
"body2": item.gsx$body2.$t,
"body3": item.gsx$body3.$t,
"body4": item.gsx$body4.$t,
"body5": item.gsx$body5.$t,
"body6": item.gsx$body6.$t,
"body7": item.gsx$body7.$t,
"body8": item.gsx$body8.$t,
"body9": item.gsx$body9.$t,
"body10": item.gsx$body10.$t,
"body11": item.gsx$body11.$t,
"body12": item.gsx$body12.$t,
"body13": item.gsx$body13.$t,
"body14": item.gsx$body14.$t,
"body15": item.gsx$body15.$t,
"body16": item.gsx$body16.$t,
"body17": item.gsx$body17.$t,
})
});
// stash the data locally for developing without
// needing to hit the API each time.
seed(JSON.stringify(data), `${__dirname}/../dev/sheet.json`);
// resolve the promise and return the data
resolve(data);
})
// uh-oh. Handle any errrors we might encounter
.catch(error => {
console.log('Error :', error);
reject(error);
});
})
}
In module.exports gibt es ein Promise, das unsere Daten auflöst oder bei Bedarf Fehler auslöst. Sie werden feststellen, dass ich axios verwende, um die Daten aus der Tabelle abzurufen. Ich mag es, dass es Statusfehlercodes behandelt, indem es das Promise automatisch ablehnt, im Gegensatz zu etwas wie Fetch, bei dem Fehlercodes manuell überwacht werden müssen.
Ich habe dort ein data-Objekt mit einem content-Array darin erstellt. Ändern Sie die Struktur des Objekts gerne, je nachdem, wie die Tabelle aussieht.
Wir verwenden die forEach()-Methode, um jede Tabellenspalte zu durchlaufen und sie mit dem entsprechenden Namen, den wir ihr zuweisen möchten, gleichzusetzen, während all dies als Inhalt in das Datenobjekt eingefügt wird.
Erinnern Sie sich an den seed-Befehl von vorhin? Wir verwenden seed, um den Inhalt des Datenobjekts mittels JSON.stringify in JSON zu transformieren, das dann an src/site/_data/dev/sheet.json gesendet wird.
Ja! Jetzt haben wir Daten in einem Format, das wir mit jeder Vorlagen-Engine, wie z. B. Nunjucks, manipulieren können. Da wir uns in diesem Projekt jedoch auf den Inhalt konzentrieren, werden wir das Vorlagenformat index.md verwenden, um die im Projekt gespeicherten Daten zu kommunizieren.
Zum Beispiel sieht es so aus, wenn man item.header über eine for-Schleife abruft
<div class="listing">
{%- for item in sheet.content -%}
<h1>{{ item.header }} </h1>
{%- endfor -%}
</div>
Wenn Sie Nunjucks oder eine andere Vorlagen-Engine verwenden, müssen Sie die Daten entsprechend abrufen.
Zuletzt bauen wir das auf
npm run build
Beachten Sie, dass Sie einen dist-Ordner im Projekt benötigen, in den der Build-Prozess die kompilierten Assets senden kann.
Aber das ist noch nicht alles! Wenn wir die Google-Tabelle bearbeiten würden, würden wir nichts auf unserer Website aktualisiert sehen. Hier kommt Zapier ins Spiel. Wir können Google Sheet und Netlify "zappen", sodass eine Aktualisierung der Google-Tabelle einen Deployment von Netlify auslöst.
Unter der Annahme, dass Sie ein Zapier-Konto haben und es läuft, können wir den Zap erstellen, indem wir Google und Netlify die Berechtigung erteilen, miteinander zu kommunizieren, und dann Trigger hinzufügen.
Das Rezept, nach dem wir suchen? Wir verbinden Google Sheets mit Netlify, damit Netlify ein Deployment startet, wenn eine "neue oder aktualisierte Tabellenzeile" stattfindet. Es ist wirklich eine "einrichten und vergessen"-Angelegenheit.

Juhu, da haben wir es! Wir haben eine performante statische Website, die ihre Daten aus Google Sheets bezieht und automatisch bereitgestellt wird, wenn Aktualisierungen an der Tabelle vorgenommen werden.
Das ist genau das, wonach ich gesucht habe, David!
Vielen Dank für das Teilen.
Gern geschehen, Dan.
Fantastisch nützlich. Glauben Sie, dass dies gut für ein E-Mail-CMS funktionieren würde?
Was ist ein E-Mail-CMS?
Lustig, ich hatte denselben Gedanken, als ich das las. Ich denke, es hat definitiv Potenzial. Wir verwenden heute eine Kombination aus Python & Jekyll, um E-Mails aus Inhalten zu erstellen, die unsere Redakteure in eine Google-Tabelle eintragen. Es fehlen einige der hier gezeigten Automatisierungen wie "Im Web veröffentlichen" zur Ausführung des Builds. Ich bin jedoch zuversichtlich, dass es basierend auf einigen der hier genannten Ideen einen Weg gibt, dies zu tun.
Es scheint großartig, aber ich bin bei
npm installsteckengeblieben. Es erstellt eine package-lock.json-Datei und installiert nichts.Gibt es eine Möglichkeit, die erforderlichen Pakete aufzulisten? Sollte das Repository eine package.json-Datei enthalten?
Hier ist, was ich von diesem npm install erhalte
npm WARN saveError ENOENT: no such file or directory, open ‘C:\MYLOCALFOLDER\Please-edit-me\package.json’
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open ‘C:\MYLOCALFOLDER\Please-edit-me\package.json’
https://github.com/Atanda1/11tywithgooglesheet
Bist du in diesem Repo?
Es ist auch möglich, auf Inhalte einer Google-Tabelle als CSV-Datei zuzugreifen, sodass sie ohne spezielle Pakete leicht verarbeitet werden kann. Tatsächlich kann sie nur jeweils ein Blatt aus der Datei verarbeiten. So etwas wie https://docs.google.com/spreadsheets/d/e/…ids und Zeichen…/pub?gid=…die ID des Arbeitsblattes…&single=true&output=csv
Nur zur Info. Für sehr leichte Projekte oder für Nicht-Node-Projekte (PHP, jemand?) könnte das ausreichen.