Für jede Art von Inhalt, die Sie für Ihre Website benötigen, entwickeln Sie in drei Schritten
- Erstellen Sie den benutzerdefinierten Inhaltstyp und konfigurieren Sie seine Felder
- Richten Sie Ihre App so ein, dass sie diese Inhalte aus der API abruft
- Laden Sie den Inhalt in Ihre Seitenvorlage
Werfen wir einen genaueren Blick auf jeden dieser Schritte, während ich erläutere, wie Sie eine einfache Nachrichten-Website (Demo-Website) mit einer Homepage und Artikelseiten einrichten.
1) Artikelseiten
Erstellen Sie den benutzerdefinierten Inhaltstyp "Artikel"
Bei der Entwicklung eines benutzerdefinierten Inhaltstyps müssen Sie alle benötigten Inhaltsfelder ermitteln. Ein Blogbeitrag kann beispielsweise eine Kombination aus Text, Bildern und Blockzitaten sein. Für ein Produkt müssten Sie die Bildfelder, Zahlenfelder und Textfelder definieren, die für das Design Ihrer Produktseite spezifisch sind.
Für unsere Artikelseiten benötigen wir eine UID (eindeutige ID für SEO-freundliche URLs), ein Veröffentlichungsdatum, einen Titel, ein Hauptbild, einen Autor und drei verschiedene wiederholbare Abschnitte, die gemischt werden können: Text, Zitate und Bilder.
Der Prozess zum tatsächlichen Erstellen des benutzerdefinierten Typs variiert von CMS zu CMS, aber am Ende erhalten wir einen benutzerdefinierten Typ, der alle Felder enthält, die wir mit Inhalten füllen müssen. So sieht unser benutzerdefinierter Artikeltretyp aus

Das CMS, das ich verwende, ist prismic.io, obwohl jedes CMS, das JSON ausgibt, angepasst werden könnte. CSS-Tricks hat beispielsweise eine Reihe von Artikeln über die WordPress JSON API und es scheint, dass Perch Runway 3 "Headless CMS"-Funktionen haben wird. Prismic verwendet ebenfalls JSON, um Ihre benutzerdefinierten Typen zu erstellen und Ihre Inhaltsfelder zu konfigurieren. Den JSON-Code, den ich für meine benutzerdefinierten Typen für dieses Projekt verwendet habe, finden Sie im Projektpaket auf GitHub. Sie finden ihn im Ordner `customTypes`.
Sobald Sie Ihren benutzerdefinierten Artikeltretyp erstellt und konfiguriert haben, erstellen Sie einige Artikel, und als Nächstes sehen wir, wie Sie die API abfragen, um sie abzurufen.
Richten Sie die Frontend-Anwendung ein, um die API abzufragen und die Artikel zu laden
Hier glänzt ein API-basiertes CMS wirklich. Sie können Ihre Website nach Belieben mit jeder bevorzugten Technologie erstellen. Viele der verfügbaren API-basierten CMS bieten spezifische Entwicklungskits für die wichtigsten Technologien, die alle benötigten Methoden zum Abfragen der API und zum Parsen der zurückgegebenen Daten bereitstellen. Dies erleichtert die schnelle Einrichtung Ihres Projekts.
Unabhängig davon, womit Sie programmieren, müssen Sie die API abfragen, um die anzuzeigenden Inhalte abzurufen. Ich habe diese Beispiel-Website mit dem NodeJS-Entwicklungs-Kit von prismic.io erstellt. Ich habe NodeJS gewählt, weil es eine einfache und unkomplizierte serverseitige JavaScript-Plattform ist.
Lassen Sie uns unsere Anwendung so einrichten, dass die Seiten über ihre UIDs geladen werden. Hier ist ein Beispiel für den Code, den wir zum Abfragen der API für unsere Inhaltseiten verwenden können.
app.route('/:uid').get(function(req, res) {
var uid = req.params.uid;
api(req, res).then(function(api) {
// Here we are querying for a custom type ‘article’ by its unique ID
return api.getByUID('article', uid);
}).then(function(pageContent) {
res.render('article', {
pageContent: pageContent
});
});
});
Laden Sie den Inhalt in die Seitenvorlagen
Sobald wir die benötigten Inhalte aus der API abgerufen haben, müssen wir nur noch die Inhalte in unseren Vorlagen laden. Unsere API-Abfrage liefert ein JSON-Objekt, das alle unsere Inhalte enthält.
Die Entwicklungskits enthalten auch Hilfsfunktionen, die das einfache Laden von Inhalten in unsere Vorlagen erleichtern.
Diese Beispielwebsite verwendet das Pug (früher Jade) Templating-System zur Erstellung des HTML für die Seiten. Die Integration der Seiteninhalte ist schnell und einfach. Alles, was wir tun müssen, ist, unsere statischen Inhalte durch die aus der API abgefragten Inhalte zu ersetzen.
Unten füge ich den Code zur Integration der Inhalte in die Vorlage ein, aber keine Abschnitte wie Header oder Layout-Dateien. Wenn Sie diese sehen möchten, können Sie sich gerne das vollständige Projekt auf GitHub ansehen.
extends ./layout.pug
block body
include ./partials/header.pug
div.article.container
include ./partials/back.pug
h1
//- Here we insert the StructuredText field ‘title’ from the custom type ‘article’
!= pageContent.getStructuredText('article.title').asText() || 'Untitled'
img.article-image(src=pageContent.getImage('article.image').url, class='star')
- var sliceZone = pageContent.getSliceZone('article.body') || {}
for slice in sliceZone.slices
//- Render the right markup for a given slice type.
case slice.sliceType
// Text Section
when 'text'
div.article-section.text
!= slice.value.asHtml()
// Quote Section
when 'quote'
div.article-section.quote
span.block-quotation !{slice.value.asText()}
// Image Section
when 'image-with-caption'
- var imageWithCaption = slice.value.toArray()[0]
- var imageUrl = imageWithCaption.getImage('illustration') ? imageWithCaption.getImage('illustration').url : ''
- var caption = imageWithCaption.get('caption')
div.article-section.image
img(src=imageUrl)
if caption
p
span.image-label !{caption.asText()}
include ./partials/back.pug
Wir zeigen nun erfolgreich die Seiten für unsere Website an! Wir werden diesen gleichen Prozess kurz durchlaufen, um unsere Homepage einzurichten.
2) Homepage & Layout
Erstellen Sie den benutzerdefinierten Inhaltstyp "Layout"
Wir benötigen einen benutzerdefinierten Typ für das Layout der Website. Dieser wird Text für das Logo, den Link zu diesem Artikel und den Text für diesen Link enthalten. Die Homepage selbst wird aus den Inhalten aller Artikel bestehen, sodass wir keinen benutzerdefinierten Typ dafür erstellen müssen.

Rufen Sie die API ab und laden Sie die Homepage
Um alle benötigten Inhalte für die Homepage zu erhalten, rufen wir die API tatsächlich zweimal auf. Einmal, um die Layout-Inhalte abzurufen, und dann noch einmal, um alle Artikel in Kacheln auf der Homepage anzuzeigen. So könnte das mit NodeJS aussehen
// Route for homepage
app.route('/').get(function(req, res) {
api(req, res).then(function(api) {
// Query the site-layout content
api.getSingle("site-layout").then(function(layout) {
// Then query all the articles and sort by date
api.query(
prismic.Predicates.at("document.type", "article"),
{ orderings: '[my.article.date desc]' }
).then(function(articles) {
res.render('homepage', {
layout: layout,
articles: articles.results
});
}).catch(function(err) {
handleError(err, req, res);
});
}).catch(function(err) {
handleError(err, req, res);
});
});
});
Laden Sie den Inhalt in die Homepage-Vorlage
Dann ist es nur noch eine Frage des Ladens des Layouts und des Artikelinhalts in die Homepage-Vorlage. Um den Layout-Inhalt hinzuzufügen, müssen Sie nur die Datei `header.pug` aktualisieren.
header
a(href="./")
p.logo
!= layout.getText('site-layout.logo')
a.article-link(href=layout.getLink('site-layout.link').url() target="_blank")
!= layout.getText('site-layout.link-text')
Auf der Homepage wird der aktuellste Artikel ganz oben angezeigt. Wir nehmen also den ersten Artikel und laden ihn in diese Vorlage.
div.featured-article-container
div.featured-article(style="background-image: url(" + article.getImageView("article.image", "featured").url + ");")
div.featured-content
h2
!= article.getStructuredText('article.title').asText() || 'Untitled'
//- display first valid slice text and limit it respecting the end of words.
- var firstParagraph = article.getFirstParagraph()
- var firstParagraphInPost = firstParagraph ? firstParagraph.text : ''
- var textLimit = 100
- var limitedText = firstParagraphInPost.substr(0, textLimit)
p.description
if firstParagraphInPost.length > textLimit
= limitedText.substr(0, limitedText.lastIndexOf(' ')) + '...'
else
= firstParagraphInPost
a.button.featured-button(href=ctx.linkResolver(article)) Read the article
Dann müssen Sie nur noch die restlichen Artikel integrieren.
div.article-tile
div.article-tile-image(style="background-image: url(" + article.getImageView('article.image', 'tile').url + ");")
img.article-tile-mobile-image(src=article.getImageView('article.image', 'tile-mobile').url)
div.article-tile-content
h2
!= article.getStructuredText('article.title').asText() || 'Untitled'
p.meta-info
!= article.getText('article.author')
span.date -
!= ctx.dateConverter(article.getTimestamp('article.date'))
//- display first valid slice text and limit it respecting the end of words.
- var firstParagraph = article.getFirstParagraph()
- var firstParagraphInPost = firstParagraph ? firstParagraph.text : ''
- var textLimit = 300
- var limitedText = firstParagraphInPost.substr(0, textLimit)
p.description
if firstParagraphInPost.length > textLimit
= limitedText.substr(0, limitedText.lastIndexOf(' ')) + '...'
else
= firstParagraphInPost
a.button(href=ctx.linkResolver(article)) Read the article
Nach Abschluss der Integration ziehen wir nun erfolgreich Inhalte aus der API und zeigen sie auf unserer Website an!
3) Andere Verwendungen
Ein weiterer Vorteil der Verwendung von API-basierten CMS ist, dass Sie Inhalte auch in anderen Formaten abfragen und laden können, z. B. für Handy-Apps. Um dies zu demonstrieren, habe ich auch eine iOS-App erstellt, die dieselbe API abfragt und die Nachrichtenartikel auf Ihrem Smartphone anzeigt.
Ich habe die App mit React Native erstellt und bin dabei dem gleichen Prozess wie oben gefolgt. Ich habe React Native gewählt, weil es Ihnen ermöglicht, reichhaltige mobile Benutzeroberflächen nur mit JavaScript zu erstellen. Obwohl ich nur eine iOS-App erstellt habe, macht React Native es auch einfach, Ihre App unter Android auszuführen.
Mit den bereits vorhandenen benutzerdefinierten Typen können Sie mit dem Abfragen der API beginnen. Ich stelle unten einige Beispielcodes zur Verfügung, aber Sie können das gesamte Projekt gerne hier in meinem GitHub-Repository einsehen. Hier ist die Abfrage, um die Inhalte eines Artikels zu erhalten.
// The query for the article
async function article (uid) {
try {
const api = await PrismicHelper.getApi()
const layoutDoc = await api.getSingle('site-layout')
const articleDoc = await api.getByUID("article", uid)
return {layoutDoc, articleDoc}
} catch(error) {
console.log(error);
return {};
}
}
Sobald Sie die Inhalte abgefragt haben, können Sie sie in Ihren Ansichten mit denselben Methoden anzeigen, die wir oben für unsere NodeJS-Website verwendet haben. Auch hier ein Beispiel dafür, wie es aussieht.
<ScrollView>
<StatusBar
hidden
/>
<View style={styles.container}>
<Text style={styles.logo}>
{layoutDoc.getText('site-layout.logo')}
</Text>
<TouchableHighlight onPress={ () => this._navigate() } underlayColor='rgba(0,0,0,0)'>
<Text style={styles.back}>← back to list</Text>
</TouchableHighlight>
<Text style={styles.title}>
{article.getStructuredText('article.title').asText()}
</Text>
<Image source={{uri: article.getImage('article.image').url}} style={[styles.mainImage, styles.section]} resizeMode="cover"/>
{ !content ?
<Text>Content is missing, try again later</Text>
:
<View style={styles.contentWrapper}>
{content}
<TouchableHighlight onPress={ () => this._navigate() } underlayColor='rgba(0,0,0,0)'>
<Text style={styles.back}>← back to list</Text>
</TouchableHighlight>
</View>
}
</View>
</ScrollView>
Der Vorteil der Erstellung einer Handy-App, die von der Website getrennt ist, besteht darin, dass Sie eine bessere Verbindung zu Ihrem Publikum herstellen und es ihm erleichtern können, über seine Handys auf Ihre Inhalte zuzugreifen. Sie können es sogar auf die nächste Stufe heben und bei jeder Veröffentlichung eines neuen Artikels Push-Benachrichtigungen senden und Ihr Publikum wirklich auf dem Laufenden halten. Ich fand es sehr einfach, Benachrichtigungen mit Urban Airship zu integrieren.
Ich hoffe, dieser Artikel gibt eine gute Vorstellung davon, was Sie vom API-basierten CMS-Ansatz erwarten können. Ich liebe die Freiheit und das Maß an Kontrolle, das ein API-basiertes CMS bietet. Beginnen Sie mit der Einrichtung Ihrer Inhaltstypen genau für das, was Sie brauchen. Dann können Sie die Technologie und das Templating-System verwenden, das am besten für Sie und Ihr Projekt geeignet ist. Und schließlich verbinden Sie sich mit der API, um Ihre Inhalte einfach in Ihre Vorlagen zu integrieren.
Ich liebe den Artikel, aber meiner Meinung nach fehlt ein wichtiger Punkt: Die Website sollte auf die gleiche Weise wie die mobile App erstellt werden, indem die CMS direkt abgefragt wird, und nicht durch einen Server, der als Proxy fungiert und das CMS abfragt.
Ob es sich um Node.js oder etwas anderes handelt, die Einbeziehung einer Serverumgebung bricht die sofortige Skalierbarkeit und Flexibilität, die Sie durch direkte Abfrage des CMS erhalten. Ich empfehle, das statische Frontend (HTML, CSS und JS) in der Cloud zu hosten (z. B. S3 für die Speicherung mit CloudFront für die Bereitstellung), was Ihnen eine völlig automatische, wartungsfreie Skalierbarkeit ermöglicht. Lassen Sie das CDN die Bereitstellung des Frontends übernehmen und das CMS die Bereitstellung des Backends.
(Die nächste Frage ist natürlich, was tun wir mit Suchmaschinen und anderen Crawlern? Nun, wir binden entweder eine isomorphe JS-Umgebung ein, um das Frontend auf einem Server nur für Crawler zu emulieren, oder wir crawlen unsere Website selbst und liefern die Inhalte auch statisch an Crawler. Dies ist auf jeden Fall ein eigener Artikel.)
Unabhängig von meinem vorherigen Kommentar – wenn Sie NodeJS verwenden und nicht ES2017 wie das React-Beispiel, können Sie immer noch all diese Verschachtelungen und Wiederholungen vermeiden, indem Sie die Promises verketten.
Ich mag diesen Ansatz sehr. Ich nehme es gerne weiter und baue ein komplett statisches Frontend, bei dem ich die Daten zur Entwicklungszeit aus dem CMS abrufe und in einer JSON / YAML-Datei speichere, und diese Daten dann zur Rendern der Pug-Vorlagen verwende.
Auf diese Weise gibt es buchstäblich keine ` Verzögerung ` , um die Daten zu erhalten, wenn die Seite angefordert wird – der Inhalt ist bereits zu HTML kompiliert und wird sofort ausgeliefert.
Prismic.io / Contentful sind dafür großartig – aber Sie können auch Dienste wie Airtable oder das ausgezeichnete, noch in der Alpha-Phase befindliche Dato CMS in Betracht ziehen, das Skripte zum Rendern der Inhalte in statische Datendateien anbietet.
Natürlich müssen Sie jedes Mal, wenn sich der Inhalt im CMS ändert, die Website neu kompilieren – aber Hosting-CDN-Dienste wie Netlify oder Now ermöglichen die Automatisierung dieses Prozesses über Lösungen wie Webhooks / Zapier.
Das Erstellen von 100 % vorkompilierten Websites, die auf jedem CDN laufen, aber eine nicht-technisch-freundliche Admin-Oberfläche haben, ist ein wunderbares Gefühl! Verbreiten Sie das JAM :)
Hallo, denken Sie, es ist möglich, diesen Ansatz mit AngularJS zu verwenden? Man müsste es irgendwie vielleicht über PHP in die Vorlage drucken, damit es auf dem Server und nicht auf dem Client passiert?
Der einzige Nachteil, den ich bei einem API-basierten CMS sehe, ist, wenn der Entwickler das CMS extern hostet und nur JavaScript verwendet, um Daten auf seine Seite zu AJAXen. Dann, wenn eine ausfällt, hosten Sie keine Inhalte, sodass Sie eine ziemlich gute Ausfallsicherheit wie das Caching auf dem Client-Server benötigen würden.
Wahr, aber dasselbe gilt, wenn Sie *kein* API-basiertes CMS haben und es ausfällt ;) Sie müssen in beiden Szenarien Skalierbarkeit und Verfügbarkeit planen, aber das Headless-CMS-Szenario ist *deutlich* einfacher zu skalieren.
Ich habe eine Website mit Prismic und React erstellt, es war eine Freude, mit beiden Technologien zu arbeiten, und es dauerte nur wenige Minuten, um die CMS-Seite den Kunden zu erklären.
Eine Sache, die mich beunruhigt, ist jedoch, wenn Prismic (oder der von Ihnen verwendete Dienst) seine Geschäftstätigkeit einstellt.
Gut für SPA oder RIA, aber schlecht für "normale" Websites. Es beeinträchtigt die Leistung und den Benutzer.
https://adactio.com/journal/11512
Abgesehen von den Schwierigkeiten für Bots und SEO
Danke für den Artikel… obwohl ich ihn verloren habe, als ich versucht habe, die Pug-Vorlagen zu lesen.
Ich habe Prismic verwendet und kann nur positive Dinge über das Produkt und das Team dahinter sagen. Einfach zu bedienen, schöne Benutzeroberfläche, schnelle Reaktionen vom Support und vor allem können Sie JSON rendern, wann immer Sie können, sogar verrückte Sachen wie 3D mit WebGL und so weiter..