Dokumentation

Scopes / Kontexte

Datenquellen für Website-Seiten und Komponenten pflegen und im Code nutzen.

Allgemein

Scopes und Kontexte versorgen Website-Seiten und Website-Komponenten mit vorbereiteten Daten. Dadurch muss der Code einer Seite nicht bei jedem Aufruf selbst herausfinden, welche Artikel, Events, Beiträge, Warenkorb- oder Plugin-Daten geladen werden sollen. Die ausgewählten Datenquellen werden beim Rendern der Seite oder Komponente aufgelöst und anschließend als Runtime-Properties bereitgestellt. Die alten MCP-Scopes sind deprecated und sollten für neue Webseiten nicht mehr verwendet werden.

Verfügbarkeit

Welche Scopes und Kontexte verfügbar sind, hängt von der aktuellen simplebis-Umgebung und von der Website ab. Entscheidend sind der aktivierte Modulumfang der Umgebung, die installierten Plugins und die auf der Website aktivierten Plugins. Ist ein Modul nicht aktiv oder ein Plugin nicht installiert beziehungsweise nicht für die Website aktiviert, werden die zugehörigen Kontexte nicht angeboten und können beim Rendern nicht aufgelöst werden. Presets können zusätzlich eigene Kontexte mitbringen, zum Beispiel für Artikel, Events, Beiträge oder den Warenkorb.

Im Manager

Die Pflege erfolgt im simplebis-manager unter Webseiten. Dort eine Website öffnen und anschließend die gewünschte Seite oder Server-Code-Komponente bearbeiten. Bei Seiten befindet sich der relevante Bereich im Abschnitt Scopes; bei Server-Komponenten gibt es den Abschnitt Plugin-Kontexte. Über Kontext hinzufügen wird ein verfügbarer Kontext gewählt, ein Daten-Key vergeben und die benötigten Parameter werden gepflegt. Der Daten-Key bestimmt, unter welchem Namen das Ergebnis später im Code erreichbar ist, zum Beispiel articles, events, posts oder cart. Ein Daten-Key darf innerhalb derselben Seite oder Komponente nur einmal aktiv verwendet werden.

Auflösung beim Laden

Beim Laden einer Code-Seite oder einer Server-Code-Komponente werden die verbundenen Scopes und Kontexte direkt serverseitig aufgelöst. Das Ergebnis wird der Seite oder Komponente über die Runtime-Properties übergeben: data enthält die aufgelösten Daten, props enthält die gepflegten Komponenten-Properties und api enthält Hilfsfunktionen wie api.renderComponent, api.routeParams, api.searchParams und weitere Website-APIs. Plugin-Kontexte werden nach den Basisdaten aufgelöst und können deshalb bereits vorhandene Scope-Daten berücksichtigen. Wenn ein Kontext nicht geladen werden kann, sollte Code defensiv mit null, leeren Listen oder fehlenden Keys umgehen.

Seiten und Komponenten

Scopes und Plugin-Kontexte werden für Code-Seiten und Server-Code-Komponenten aufgelöst. Client-Komponenten erhalten diese serverseitig geladenen Kontextdaten nicht automatisch. Wenn eine Client-Komponente Kontextdaten anzeigen soll, sollte eine Code-Seite oder Server-Komponente die Daten entgegennehmen und sie als normale Properties an die Client-Komponente weiterreichen. Wird eine Server-Komponente über api.renderComponent("Name", props) geladen, werden die an dieser Komponente gepflegten Kontexte ebenfalls beim Rendern der Komponente aufgelöst.

Eingebaute Daten

Neben Plugin-Kontexten existieren eingebaute Website-Scopes, die von simplebis oder Presets genutzt werden können. Beispiele sind cart für den aktuellen Warenkorb, shop_categories für aktive Shop-Kategorien, shop_articles für aktive Shop-Artikel, shop_article_details für einen Shop-Artikel, events_list für Eventlisten und event_details für ein einzelnes Event. Plugin- und Preset-Kontexte nutzen dagegen den im Editor gesetzten Daten-Key, zum Beispiel articles, article_categories, events, posts, post_categories oder cart.

Parameter und URL-Werte

Kontexte können feste Parameter und URL-bezogene Werte verwenden. Je nach Kontext werden zum Beispiel ein Shop, eine Kategorie, ein Artikel, ein Event, ein Limit, eine Sortierung oder die Option URL-Filter verwenden gepflegt. Beim Rendern stehen außerdem Routenparameter und Query-Parameter zur Verfügung. Eine Seite wie /shop/:shop/:category kann dadurch den aktuellen Shop oder die aktuelle Kategorie aus der URL verwenden, ohne dass der Seiten-Code die Datenquelle selbst initialisieren muss.

Zugriff in Code-Seiten

In einer Code-Seite wird das aufgelöste Ergebnis über data gelesen. Der Key entspricht dem Daten-Key aus dem Manager oder dem festen Target-Key eines eingebauten Scopes. Das folgende Beispiel erwartet einen Plugin-Kontext mit dem Daten-Key articles.

const React = require("react");

exports.default = async function ArticleOverviewPage({ data, api }) {
  const result = data?.articles || {};
  const entries = Array.isArray(result.entries) ? result.entries : [];

  return React.createElement(
    "main",
    { className: "article-overview" },
    React.createElement("h1", null, "Artikel"),
    entries.length < 1
      ? React.createElement("p", null, "Keine Artikel gefunden.")
      : React.createElement(
          "div",
          { className: "article-grid" },
          entries.map((article) => React.createElement(
            "article",
            { key: article._id || article.url_slug || article.name, className: "article-card" },
            React.createElement("h2", null, article.name || article.title || "Artikel"),
            article.short_description
              ? React.createElement("p", null, article.short_description)
              : null,
          )),
        ),
  );
};

Wenn derselbe Datenbestand an eine Komponente weitergegeben werden soll, kann die Seite ihn als normale Property übergeben, zum Beispiel api.renderComponent("ArticleList", { articles: entries }).

Zugriff in Code-Komponenten

In einer Server-Code-Komponente funktioniert der Zugriff gleich: Die Komponente erhält data, props und api. Dieses Beispiel liest standardmäßig den Daten-Key events, erlaubt aber über eine Komponenteneigenschaft dataKey einen anderen Key.

const React = require("react");

exports.default = async function EventTeaserList({ props, data }) {
  const dataKey = props?.dataKey ? props.dataKey.toString().trim() : "events";
  const result = data?.[dataKey] || {};
  const entries = Array.isArray(result.entries) ? result.entries : [];

  if (entries.length < 1) {
    return null;
  }

  return React.createElement(
    "section",
    { className: "event-teasers" },
    entries.map((event) => React.createElement(
      "article",
      { key: event._id || event.url_slug || event.title, className: "event-teaser" },
      React.createElement("h2", null, event.title || "Veranstaltung"),
      event.begin ? React.createElement("time", null, event.begin) : null,
    )),
  );
};

Der Vorteil ist, dass dieselbe Komponente mit unterschiedlichen Kontexten wiederverwendet werden kann, solange der Daten-Key im Manager passend gesetzt wird.

Weitergabe an Client-Komponenten

Client-Komponenten sollten fertig vorbereitete Daten als normale Properties erhalten. Eine Server-Komponente kann zum Beispiel einen Kontext mit dem Daten-Key articles laden und anschließend eine Client-Komponente rendern.

const React = require("react");

exports.default = async function ArticleClientBridge({ data, api }) {
  const entries = Array.isArray(data?.articles?.entries) ? data.articles.entries : [];
  return api.renderComponent("ArticleListClient", { articles: entries });
};

Die Client-Komponente liest dann props.articles. Sie muss den Kontext nicht selbst kennen und bekommt keine serverseitigen Scope-Konfigurationen ausgeliefert.

Prüfung

Wenn Kontextdaten nicht wie erwartet erscheinen, sollten zuerst Modulstatus, Plugin-Installation, Website-Plugin-Aktivierung, Kontext-Aktivierung, Daten-Key, Parameter und URL-Parameter geprüft werden. Danach sollte geprüft werden, ob die betroffene Komponente eine Server-Komponente ist oder ob Daten an eine Client-Komponente explizit per Props weitergereicht werden müssen. Für dynamische Seiten empfiehlt sich ein Test mit realen URLs, zum Beispiel mit konkretem Shop-, Kategorie-, Artikel- oder Event-Slug.