Scrivito wird von der JustRelate Group mit viel Erfahrung und Leidenschaft in Berlin und in Breslau, Polen, entwickelt.
Scrivito wird von der JustRelate Group entwickelt.

Website-Einstellungen mit Konfigurationsobjekten und eigenen Dialogen pflegen

Website-Einstellungen mit Konfigurationsobjekten und eigenen Dialogen pflegen

Die meisten Websites als Ganzes erfordern ein gewisses Maß an Konfiguration. So kann man beispielsweise als Redakteur in der Scrivito Example App das anzuzeigende Logo festlegen, IDs für die Authentifizierung gegenüber Diensten wie Google Analytics eintragen und noch einige andere Einstellungen vornehmen. Hierfür navigiert der Redakteur zur Homepage, klickt im Menü auf „Seiteneigenschaften bearbeiten“, wählt die Registerkarte „Site settings“und nimmt dann die gewünschten Änderungen dort vor.

Es ist gängige Praxis und oft ausreichend, Website-Einstellungen an die Homepage zu knüpfen, jedoch ist diese Herangehensweise nicht immer die praktischste für Redakteure, denn:

  • Man muss zur Homepage navigieren, um auf die Einstellungen zugreifen zu können.
  • Es ist nicht immer klar, welche dieser Einstellungen sich auf die Website insgesamt, und welche sich nur auf die Homepage beziehen.
  • Früher oder später wird der „Seiteneigenschaften“-Dialog unübersichtlich aufgrund der vielen Einstellmöglichkeiten.

Wir möchten Ihnen hier eine flexiblere Lösung für die Handhabung von Website-Einstellungen vorstellen, unabhängig von deren Art: Da man mit Scrivito das Hauptmenü erweitern sowie Dialoge öffnen kann, ist es naheliegend, diese Features zur Bearbeitung globaler Einstellungen zu nutzen. In diesem Artikel zeigen wir, wie man die Eigenschaften eines Coupons bearbeitbar machen kann, eines Coupons, der auf einer beliebigen Anzahl Seiten angezeigt werden können soll. Solche Eigenschaften könnten natürlich auch andere Website-Einstellungen umfassen…

Eine Objektklasse für Konfigurationen definieren

Um Einstellungen zu persistieren und unabhängig von einer bestimmten Seite darauf zugreifen zu können, bietet es sich an, ein Konfigurationsobjekt zu verwenden, ein gewöhnliches CMS-Objekt, das mit den erforderlichen Attributen, passend zu der Art der zu speichernden Daten, ausgestattet ist.

Was wir hier umsetzen möchten, ist, wie oben angekündigt, ein Coupon, der mit Hilfe eines Widgets auf mehreren Seiten der Website angezeigt werden kann. Da wir annehmen, dass dieser Coupon mindestens einmal täglich geändert wird, wäre es zu fehleranfällig und zeitraubend, jedes dieser Widgets einzeln bearbeiten zu müssen. Stattdessen werden wir eine einzige Coupon-Konfiguration anlegen, auf die sämtliche dieser Widgets dann zurückgreifen.

Lassen Sie uns also als erstes eine Objektklasse anlegen, CouponConfig, mit je einem Attribut für den couponCode sowie die message dazu für den Besucher:

src/Objs/CouponConfig/CouponConfigObjClass.js
import * as Scrivito from "scrivito";

const CouponConfig = Scrivito.provideObjClass("CouponConfig", {
  attributes: {
    couponCode: "string",
    message: "html",
  },
});

export default CouponConfig;

Im nächsten Schritt definieren wir die Konfiguration für die Bearbeitung von Objekten dieser Klasse, obwohl CouponConfig-Objekte gar keine Seiten sind und es daher keine Möglichkeit gibt, Attributwerte zu bearbeiten. Allerdings ist es naheliegend, couponCode und message zu Testzwecken mit Werten vorzubelegen. Außerdem ist es wichtig, dafür zu sorgen, dass Redakteure keine weiteren CouponConfig-Objekte anlegen können.

src/Objs/CouponConfig/CouponConfigEditingConfig.js
import * as Scrivito from "scrivito";

Scrivito.provideEditingConfig('CouponConfig', {
  hideInSelectionDialogs: true,
  initialContent: {
    couponCode: 'BOOKS15OFF',
    message: 'Get 15 % off on all books today!',
  },
});

Aus dem genannten Grund (die Objekte sind keine Seiten) benötigen wir keine Komponente, die CouponConfig-Objekte rendert. Stattdessen stellen wir eine Komponente zur Verfügung, die der Funktion openDialog zum Zwecke der Bearbeitung der Attribute übergeben werden kann.

Das Konfigurationsobjekt und den -dialog bereitstellen

Jetzt, da wir sowohl die CouponConfig-Objektklasse als auch die dazugehörige Konfiguration für die Bearbeitung solcher Objekte haben, lassen Sie uns eines anlegen:

  • Führen Sie Ihre App mit npm start aus.
  • Aktivieren Sie den Bearbeitungsmodus.
  • Öffnen Sie die Browser-Konsole.
  • Setzen Sie den Kontext auf “scrivito_application”.

Führen Sie anschließend Folgendes aus:

Scrivito.getClass('CouponConfig').create({_permalink: 'couponconfig'})

Dies legt das Konfigurationsobjekt für den Coupon an und weist ihm den Permalink couponconfig zu.

Als nächstes benötigen wir die Dialog-Komponente, mit der die Attributwerte dieses Objekts bearbeitet werden sollen. Beachten Sie, dass wir hier den Permalink des Objekts nutzen, um im Dialog darauf zuzugreifen:

src/Components/ScrivitoExtensions/CouponConfigDialog.js
import * as React from "react";
import * as Scrivito from "scrivito";

function CouponConfigDialog() {
  const couponConfig = Scrivito.Obj.getByPermalink("couponconfig");
  const attributes = { couponCode: "Coupon code", message: "Message" };

  return (
    <div className="container-fluid pt-4">
      {Object.keys(attributes).map(key => (
        <div key={key} className="card mb-2">
          <div className="card-title strong ml-2 mr-2 mt-1">
            <span>{attributes[key]}</span>
          </div>
          <hr className="mt-0 mb-1" />
          <div className="pb-2">
            <Scrivito.ContentTag
              className="card-text ml-2 mr-2 mt-1"
              content={couponConfig}
              attribute={key}
            />
          </div>
        </div>
      ))}
    </div>
  );
}

Scrivito.registerComponent("CouponConfigDialog", CouponConfigDialog);

Nachdem das /couponconfig-Objekt abgerufen wurde, werden dessen Attribute couponCode und message mit Hilfe von Scrivito.ContentTag bearbeitbar gemacht. Mehr ist nicht erforderlich. Man könnte noch das Styling verbessern, bei dem wir uns hier mit Bootstrap-Klassen begnügt haben. Wenn Sie möchten, können Sie das CSS übernehmen, das auf den zusätzlichen Reitern in den Eigenschaften der Homepage verwendet wird.

Einen Menüeintrag für den Konfigurationsdialog hinzufügen

Als abschließenden Schritt fügen wir jetzt noch zum Hauptmenü einen Eintrag hinzu, der einen Dialog öffnet, in dem die obige Komponente angezeigt wird. Denken Sie bitte daran, die Datei “scrivitoExtendMenu.js” mittels “index.js” im selben Verzeichnis zu importieren.

src/config/scrivitoExtendMenu.js
import * as Scrivito from 'scrivito';
import couponConfigDialogMenuIcon from '../assets/images/arrow_next.svg';

Scrivito.extendMenu(menu => {
  menu.insert({
    id: "couponConfiguration",
    title: "Edit coupon configuration",
    icon: couponConfigDialogMenuIcon,
    onClick: () => Scrivito.openDialog('CouponConfigDialog'),
    position: { after: 'system.openPageDetails' },
    group: 'system.details',
  });
});

Das Scrivito.extendMenu-API ist ausgesprochen vielseitig. Sie können damit nicht nur Menüeinträge hinzufügen, sondern auch entfernen, verschieben, gruppieren und nicht zuletzt mit einem onClick-Event-Handler ausstatten. Letzteres ist oben dort sehen, wo Scrivito.openDialog aufgerufen wird.

Probieren Sie es aus!

Starten Sie nun bitte Ihre App und wechseln Sie in den Bearbeitungsmodus. Über das Hauptmenü rechts oben müssten Sie jetzt “Edit coupon configuration” wählen können.

Wir sind vorläufig fertig, und Sie können nach Belieben weitere Dialoge im Hauptmenü anbieten!

Das Coupon-Widget anlegen

Um unser Konfigurationsobjekt nun auch zu nutzen, hier in aller Kürze das CouponWidget, das auf unsere globalen Coupon-Einstellungen zugreift:

src/Widgets/CouponWidget/CouponWidgetClass.js
import * as Scrivito from "scrivito";

const CouponWidget = Scrivito.provideWidgetClass("CouponWidget", {});

export default CouponWidget;
src/Widgets/CouponWidget/CouponWidgetComponent.js
import * as React from "react";
import * as Scrivito from "scrivito";

Scrivito.provideComponent("CouponWidget", ({ widget }) => {
  const couponConfig = Scrivito.Obj.getByPermalink("couponconfig");

  return (
    <Scrivito.InPlaceEditingOff>
      <div className="card text-center bg-warning">
        <div className="card-body pb-0">
          <Scrivito.ContentTag
            content={couponConfig}
            attribute="couponCode"
            className="h4 mb-0 strong"
          />
          <Scrivito.ContentTag
            content={couponConfig}
            attribute="message"
            className="mt-0 strong"
          />
        </div>
      </div>
    </Scrivito.InPlaceEditingOff>
  );
});

Zu dieser Widget-Klasse gibt es keine Konfiguration für die Bearbeitung ihrer Instanzen, da für diese keine Attribute (etwa zu Styling-Zwecken) definiert werden. In unserem Fall sollen alle Widget-Instanzen, d.h. die Coupons gleich aussehen. Wäre es erwünscht, sie unabhängig voneinander mit Stilen versehen zu können, hätten wir die Attribute dafür in der Widget-Konfiguration angeben und in der Widget-Komponente berücksichtigen müssen.

Um darüber hinaus Redakteuren zu vermitteln, dass der Inhalt einzelner Coupon-Widgets (anders als erwartet) nicht geändert werden kann, wurde die in Scrivito.ContentTag integrierte Bearbeitungsmöglichkeit mittels Scrivito.InPlaceEditingOff deaktiviert. Sollte es jedoch erwünscht sein, dass sich sämtliche dieser Widgets auf einmal ändern lassen, können Sie diese Komponente entfernen.