Testen Sie Scrivito 30 Tage lang kostenlos
Testen Sie Scrivito 30 Tage lang kostenlos

Inhalte als wiederverwendbare Module erstellen

Inhalte als wiederverwendbare Module erstellen

Größere Mengen duplizierter Inhalte zu pflegen, kann sehr aufwendig sein. Haben Sie beispielsweise einen Block aus einem Text und einem Download-Button auf etlichen Landing-Pages platziert, möchten Sie sämtliche Seiten nicht einzeln bearbeiten müssen, wenn der Text oder das Linkziel der Buttons geändert werden soll. Mehrfache Vorkommen desselben Inhalts auf diese Weise zu pflegen, ist nicht nur fehleranfällig, sondern auch mühselig.

In dieser Anleitung zeigen wir Ihnen, wie man „globale Inhalte“ anlegen und pflegen kann, wobei „global“ sich auf eine Scrivito-basierte Website als Ganzes bezieht. Wir werden eine CMS-Objektklasse für Inhalte beliebiger Art sowie eine Widget-Klasse anlegen, letztere, um diese Inhalte überall dort einzufügen, wo sie benötigt werden. So können Redakteure Seitenbestandteile wiederverwenden, wo immer dies hilfreich ist. Änderungen können an Ort und Stelle vorgenommen werden und führen dazu, dass derselbe Inhalt an allen anderen Stellen ebenfalls aktualisiert wird. Solche wiederverwendbaren Fragmente nennen wir im Folgenden „Content-Module“ oder einfach nur „Module“.

Die Objektklasse „ContentModule“

Die Scrivito Example App, auf der auch diese Anleitung aufsetzt, enthält bereits Objekttypen zur Pflege von Inhalten, die überall auf der Website genutzt werden können: Author, Event und Job. Deren Instanzen können entweder als einzelne Seiten gerendert werden (da es Komponenten für sie gibt) oder auch in Übersichten, in denen nur einige ihrer Attribute verwendet werden.

Im Gegensatz dazu brauchen unsere ContentModule-Instanzen niemals als Seiten zu erscheinen. Ihr einziger Zweck besteht darin, Inhalte zusammenzuhalten, um sie wiederholt auf diversen Seiten verwenden zu können. Aus diesem Grund benötigen wir keine Komponente, die die Instanzen rendert, sondern lediglich eine Objektklasse und eine Konfiguration, damit sie angelegt und bearbeitet werden können.

Die Objektklasse

Unsere Objektklasse stattet ContentModule-Instanzen mit zwei Attributen aus, title und content. Mit ersterem können wir den Redakteuren den Zweck eines Moduls vermitteln. Letzteres ist ein widgetlist-Attribut, mit dem der Inhalt des Moduls frei zusammengestellt werden kann:

src/Objs/ContentModule/ContentModuleObjClass.js
import * as Scrivito from "scrivito"; const ContentModule = Scrivito.provideObjClass("ContentModule", { attributes: { title: "string", content: [ "widgetlist", { only: ["HeadlineWidget", "TextWidget", "ImageWidget", "ButtonWidget"] }, ], }, }); export default ContentModule;

Wir haben die widgetlist auf ein paar einfache Widget-Typen eingeschränkt, um zu verhindern, dass Redakteure riesige Module aus Struktur-Widgets (Widgets enthaltende Widgets) wie Spalten oder Boxen und ähnlichem erstellen. Die Möglichkeit, Struktur-Widgets zu einem Modul hinzuzufügen, würde es auch erlauben, Module desselben Typs zu verschachteln, was dazu führen könnte, dass sie nicht mehr funktionieren.

Die Konfiguration zur Bearbeitung

Die Konfiguration zur Bearbeitung von ContentModule-Objekten ist ausgesprochen schlank. Wir benötigen keinen Titel und keine Beschreibung für die Attribute title und content, weil deren Namen selbsterklärend sind. Die einzige Stelle, an der die Eigenschaften eines ContentModule zu sehen sind, ist der Content Browser.

src/Objs/ContentModule/ContentModuleEditingConfig.js
import * as Scrivito from "scrivito"; Scrivito.provideEditingConfig("ContentModule", { title: "Content Module", properties: ["title", "content"], });

Content-Module dem Content Browser bekannt machen

Da Content-Module nur im Content-Browser definiert oder gelöscht werden können, werden wir dessen Konfiguration entsprechend erweitern. Fügen Sie bitte die folgenden Zeilen zum Rückgabewert der Funktion defaultFilters und zur Konstanten FILTER_PRESENTATIONS hinzu:

src/config/scrivitoContentBrowser.js
function defaultFilters() { return { … _objClass: { options: { … Download: filterOptionsForObjClass("Download"), Video: filterOptionsForObjClass("Video"), ContentModule: filterOptionsForObjClass("ContentModule"), } }, … } … const FILTER_PRESENTATIONS = { … SearchResults: { title: "Search results", icon: "lens" }, Video: { title: "Videos", icon: "video" }, ContentModule: { title: "Content modules", icon: "thumbnails" }, };

Sie können nun mit Hilfe des Content Browsers Content-Module einrichten und ihnen auch einen title geben oder sogar Widgets zu ihrem content hinzufügen.

Bis jetzt können allerdings noch keine Content-Module auf Seiten platziert werden. Lassen Sie uns also ein Widget dafür erstellen.

Die „ContentModuleWidget“-Klasse

Unser Widget soll es Redakteuren ermöglichen, Content-Module zu Seiten hinzuzufügen. Hierfür benötigen wir im Widget nur ein einziges Attribut, nämlich eines, in dem das zu verwendende Modul hinterlegt werden kann. Typischerweise sind Attribute, die Objekte referenzieren, vom Typ reference, und unsere Widget-Klasse sieht dementsprechend so aus:

src/Widgets/ContentModuleWidget/ContentModuleWidgetClass.js
import * as Scrivito from "scrivito"; const ContentModuleWidget = Scrivito.provideWidgetClass("ContentModuleWidget", { attributes: { module: ["reference", { only: "ContentModule" }], }, }); export default ContentModuleWidget;

Unser Attribut heißt module, und mit only wird hier angegeben, dass es ausschließlich auf ein Objekt vom Typ ContentModule zeigen darf. Diese Einschränkung greift in dem Moment, in dem das module-Attribut bearbeitet wird und der Content Browser sich öffnet, um den Redakteur das Zielobjekt auswählen zu lassen.

Konfiguration für die Widget-Bearbeitung

Die Konfiguration für die Bearbeitung unseres ContentModuleWidgets macht lediglich das module-Attribut in den Eigenschaften der Instanzen des Widgets bearbeitbar und fügt einen Titel und eine Beschreibung des Attributs hinzu:

src/Widgets/ContentModuleWidget/ContentModuleWidgetEditingConfig.js
import * as Scrivito from "scrivito"; Scrivito.provideEditingConfig("ContentModuleWidget", { title: "Content Module", titleForContent: widget => widget.get("module") ? widget.get("module").get("title") : null, attributes: { module: { title: "Content module", description: "The kind of module to include", }, }, properties: ["module"], });

Übrigens definiert titleForContent den Text des Tooltips, der erscheint, wenn der Mauszeiger über dem „Griff“ der Widget-Instanzen schwebt.

Die Widget-Komponente

Die Hauptaufgabe der Komponente zu unserem ContentModuleWidget besteht darin, das Attribut module daraufhin zu untersuchen, ob es einen Wert hat, und, wenn dies zutrifft, das content-Attribut des ContentModule-Objekts zu rendern, auf das das Attribut zeigt:

src/Widgets/ContentModuleWidget/ContentModuleWidgetComponent.js
import * as React from "react"; import * as Scrivito from "scrivito"; import InPlaceEditingPlaceholder from "../../Components/InPlaceEditingPlaceholder"; Scrivito.provideComponent("ContentModuleWidget", ({ widget }) => { const module = widget.get("module"); const editing = Scrivito.isInPlaceEditingActive(); return ( <div> {editing && module ? ( <div className="alert-info"> Changing this module updates all its instances. </div> ) : null} {module ? ( <Scrivito.ContentTag content={module} attribute="content" /> ) : ( <InPlaceEditingPlaceholder> Select the module in the widget properties. </InPlaceEditingPlaceholder> )} </div> ); });

Abhängig davon, ob die Bedienoberfläche im „Bearbeiten“-Modus ist und ob ein module vorhanden ist, wird ein Hinweis entweder zu den Konsequenzen einer Änderung des Inhalts oder dazu angezeigt, wie man ein Modul angeben kann.

Damit sind wir auch schon fertig. Wenn Sie bereits ein ContentModule-Objekt haben, können Sie jetzt ein ContentModuleWidget (oder auch mehrere davon) zu einer Seite hinzufügen, über dessen Eigenschaften das zu verwendende ContentModule angeben und es dann direkt auf der Seite mit Inhalt versehen.

Abschließende Worte

Wiederkehrende Inhalte einfach dadurch ändern zu können, dass man eines ihrer Vorkommen entsprechend anpasst, dürfte für Redakteure eine große Hilfe sein. Dadurch entfällt die Notwendigkeit, sich an die Stellen zu erinnern, an denen diese Inhalte ebenfalls eingefügt wurden und die Anpassungen dann auch dort vorzunehmen. Dies spart eine Menge Zeit und erleichtert es erheblich, solche Fragmente zu überarbeiten.

Wenn die meisten oder alle Ihrer Content-Module aus ungefähr denselben Widgets bestehen, könnten Sie sogar einen Schritt weitergehen und die Widgets eines jeden neuen Content-Moduls bereits vorab festlegen. Wie sich Objekte mit Inhalten vorbelegen lassen, ist im Artikel Creating a Custom Page Type beschrieben.

Beachten Sie bitte, dass der obige Ansatz, globale Inhalte zu pflegen, einen kleinen Haken hat: Seiten mit Content-Modulen tauchen nicht in den Suchergebnissen auf, wenn der Suchbegriff nur in den Modulen gefunden wurde. Um dies zu beheben, müssten die Seiten, auf denen sich die Module befinden, zum Suchergebnis hinzugefügt werden. Solche Seiten können bei einer Suche mit dem Operator linksTo gefunden werden.