1. Einleitung

FirstSpirit dient der Erstellung vielseitiger und projektspezifischer Inhalte. Mit dem Modul FirstSpirit Connect for Spryker Commerce OS for Spryker Commerce OS wurde die Möglichkeit geschaffen, diese Inhalte in das E-Commerce-Shopsystem Spryker Commerce OS zu übertragen und dort zu nutzen.

Im restlichen Dokument wird anstelle von "Spryker Commerce OS" die Kurzform "Spryker" benutzt.

Des Weiteren ist die gesamte Dokumentation auf die Anbindung des Spryker B2C Demo Shops in der Version 202108.0 ausgerichtet. Die Erwähnung des Shops bezieht sich somit ausschließlich auf den B2C Demo Shop.

Das Modul kombiniert die funktionalen Stärken beider Systeme, um so die besten Vorteile zu erzielen und ein erfolgreiches Gesamtsystem zu schaffen. Dieses Gesamtsystem besteht aus zwei Bereichen, die parallel und größtenteils entkoppelt voneinander arbeiten:

FirstSpirit-seitige Komponenten

Diese Komponenten dienen der Erstellung und Pflege der redaktionellen Daten. Sie werden im JSON-Format an die jeweilige CaaS-Instanz übermittelt und aus dieser von Spryker abgefragt.

Spryker-seitige Komponenten

Diese Komponenten dienen der Einbindung der in FirstSpirit erstellten redaktionellen Inhalte. Spryker importiert diese Daten und integriert sie in den Shop.

Ein Bestandteil der Auslieferung des FirstSpirit Connect for Spryker Commerce OS for Spryker Commerce OS-Moduls ist das Referenzprojekt FirstSpirit Connect for Spryker Commerce OS Reference Project, das in Form eines GitHub-Repositories zur Verfügung steht. Die vorliegende Dokumentation orientiert sich durchgängig an dem Referenzprojekt und erläutert die mit dem Modul bereitgestellten Funktionalitäten anhand gängiger Anwendungsfälle.

Das vorliegende Dokument richtet sich sowohl an Spryker- als auch an FirstSpirit-Entwickler, die mithilfe der Dokumentation die Integration durchführen können sollen.
Es ist kein Handbuch für FirstSpirit-Redakteure.

Es wird vorausgesetzt, dass der Leser sicher in der Verwendung FirstSpirits und Sprykers sowie des CaaS und des Omnichannel Managers ist.

1.1. Funktionsumfang

FirstSpirit Connect for Spryker Commerce OS stellt Redakteuren die folgenden Möglichkeiten zur Verfügung:

  • Erstellung nativer Shop-Inhalte mit FirstSpirit

  • Zugriff auf Produkt- und Kategorieinformationen

  • gleichzeitige Darstellung von Shop-Elementen und redaktionellen Inhalten in der FirstSpirit-Vorschau

  • Übertragung von Inhalten in das Spryker Commerce OS

Die entsprechenden Funktionalitäten werden mit der Installation und Konfiguration des Moduls im ContentCreator bereitgestellt.

Die Pflege der Inhalte findet über die gewohnten FirstSpirit-Mittel statt. Mit FirstSpirit vertraute Redakteure benötigen daher keine darüber hinausgehenden Kenntnisse. Die Inhalte werden Spryker im Rahmen eines Deployments zum Import bereitgestellt. Spryker integriert die Informationen in den Shop.

Für Spryker ergibt sich somit bei der Auslieferung redaktioneller Inhalte in den Live-Stand keinerlei Unterschied. Auch wenn der FirstSpirit-Server beispielsweise aufgrund von Wartungsarbeiten heruntergefahren wird, beeinflusst dies Spryker nicht.

1.2. Architektur

Die Verbindung von FirstSpirit und Spryker wird über eine Architektur aus verschiedenen Komponenten realisiert.

Diese Komponenten sind:

  • die auf dem FirstSpirit-Server installierten Module:

    • FirstSpirit Connect for Spryker Commerce OS

    • Omnichannel Manager

    • Content as a Service

  • Spryker-Instanz

architecture
Abbildung 1. Architektur

Das Zusammenspiel der einzelnen Komponenten erfolgt immer nach dem folgenden Schema:

  1. Die Erstellung und Bearbeitung redaktioneller Inhalte findet FirstSpirit-seitig im ContentCreator statt. In diesem ist mithilfe des Omnichannel Managers die Storefront eingebettet.

  2. Die Storefront greift ihrerseits auf den Preview CaaS zu und ermittelt aus diesem die aktuellen FirstSpirit-Inhalte. Gleichzeitig bindet sie das für den Omnichannel Manager notwendige JavaScript ein, das die Bearbeitung und das Highlighting der Inhalte im ContentCreator ermöglicht.

  3. Die Übertragung der redaktionellen Inhalte in den Preview CaaS findet automatisch bei jeder Speicheraktion statt.

  4. Die Befüllung des Online CaaS mit den freigegebenen Inhalten wird durch ein Deployment angestoßen. Der Online CaaS stellt die Inhalte für den Importer zur Verfügung, der sie nach Spryker überträgt und dort persistiert.

Spryker stellt somit die Hauptkomponente dieser Architektur dar. Neben der Bereitstellung sämtlicher Shop-Funktionalitäten importiert es die in FirstSpirit erstellten bzw. gepflegten Inhalte aus dem Online CaaS und integriert sie in den Shop. Zwischen FirstSpirit und Spryker existiert lediglich eine lose Kopplung. Die beiden Systeme arbeiten hauptsächlich parallel zueinander.

1.3. Konzept

Das FirstSpirit Connect for Spryker Commerce OS-Modul bietet die Möglichkeit, redaktionelle Inhalte FirstSpirit-seitig zu pflegen und diese anschließend per Deployment an Spryker zu übertragen. Dafür muss die Verarbeitung von Inhalten in beiden Systemen aufeinander abgestimmt und zueinander kompatibel sein. Die nachfolgenden Unterkapitel beschreiben das zugrunde liegende Konzept, mit dem diese Kompatibilität erreicht wird.

1.3.1. Seiten

Ähnlich wie in FirstSpirit basieren Seiten in Spryker auf einer Struktur unterschiedlicher Komponenten. Um redaktionelle Inhalte zwischen den beiden Systemen austauschen zu können, müssen diese Komponenten aufeinander abgestimmt sein.

Innerhalb des in der Auslieferung enthaltenen Referenzprojekts FirstSpirit Connect for Spryker Commerce OS Reference Project werden die CMS Slots aus Spryker durch die Inhaltsbereiche einer Seitenvorlage in FirstSpirit repräsentiert. Ihnen können Absätze hinzugefügt werden, die jeweils einem CMS Block entsprechen.

concept
Abbildung 2. Page Rendering

Mit FirstSpirit lassen sich somit CMS Blöcke generieren, die über CMS Slots in einer Seite dargestellt werden.

1.3.2. Vorschau

Die mit dem FirstSpirit Connect for Spryker Commerce OS-Modul realisierte Integration sieht FirstSpirit-seitig lediglich die Erzeugung und Pflege der redaktionellen Inhalte sowie ihre Publizierung in Form von CMS Blöcken vor. Spryker bestimmt jedoch weiterhin das Rahmenwerk einer Seite, deren CMS Slots die generierten Blöcke einbinden.

Für die Darstellung der Vorschau einer Seite ermittelt FirstSpirit daher ihre aktuelle Ansicht in der Storefront. Diese fragt ihrerseits die redaktionellen Inhalte aus dem Preview CaaS ab und ersetzt die entsprechenden CMS Blöcke. FirstSpirit stellt das Resultat mithilfe des Omnichannel Managers im ContentCreator dar.

1.3.3. Deployment

Die Übertragung der FirstSpirit-seitig erstellten Inhalte in den Live-Stand erfolgt durch Spryker. Dafür müssen die Inhalte bereitgestellt werden, was in Form des Online CaaS geschieht. Aus ihm importiert Spryker die redaktionellen Inhalte und persistiert sie in seinem Datensystem.

1.4. Technische Voraussetzungen

Für den Einsatz des FirstSpirit Connect for Spryker Commerce OS-Moduls müssen die folgenden technischen Voraussetzungen erfüllt sein:

  • die Module FirstSpirit Connect for Spryker Commerce OS, Content as a Service und Omnichannel Manager in der jeweils aktuellen Version

  • FirstSpirit ab der Version 2022-03

  • Java 17

  • Spryker Commerce OS 202108.0 mit den Extensions Category CMS Blocks und Product CMS Blocks

  • php ab Version 7.4

Bei der Verwendung des mitgelieferten Referenzprojekts FirstSpirit Connect for Spryker Commerce OS Reference Project ist außerdem das BasicWorkflows-Modul in der jeweils aktuellen Version erforderlich.

1.5. Wichtige Hinweise

Dieses Kapitel enthält Hinweise, die bei der Verwendung des FirstSpirit Connect for Spryker Commerce OS-Moduls zu beachten sind.

1.5.1. Konfiguration des Glue-Webservers

Die in FirstSpirit gepflegten Inhalte werden während eines Deployments mithilfe des Importers aus dem Online CaaS abgefragt. Der Importer überträgt die Daten nach Spryker und persistiert sie Backend-seitig in dessen Datensystem.

Da der Online CaaS potentiell eine große Datenmenge enthält, erfordert die Übertragung der Inhalte eine gewisse Zeitspanne. Frühzeitige Timeouts während des Imports sind daher zu vermeiden. Aus diesem Grund ist der Webserver der Glue-API so zu konfigurieren, dass er http-Requests für eine Dauer von mindestens 60 Sekunden erlaubt. Zusätzlich ist FirstSpirit-seitig der Socket-Timeout bei der Kommunikation mit der Glue-API entsprechend anzupassen (siehe Kapitel Konfiguration der Projekt-Komponente).

1.5.2. Konfiguration der FirstSpirit-Einstellungsseite

Die CaaS-Generierungen setzen voraus, dass im FirstSpirit-Projekt eine Vorlage für die Projekteinstellungen gepflegt ist. Andernfalls bricht der Generierungsauftrag frühzeitig ab und meldet den folgenden Fehler in den Auftragslogs:

Exception bei fehlender Einstellungsseite
error during script execution : java.lang.IllegalStateException:
Invalid value for key 'usedCaasProjects' - Value is not a HashMap (null).
This can happen when a deployment does not include a single PageRef (blue), which is not supported (e.g. remote-media-project).

Aus diesem Grund muss im Projekt eine entsprechende Vorlage existieren und diese in den Projektoptionen im ServerManager konfiguriert sein, selbst wenn sie keinen Inhalt besitzt.

p settings
Abbildung 3. Konfiguration der Einstellungsseite in den Projektoptionen

1.5.3. Verwendung des Spryker B2C Demo Shops

Wie zuvor erwähnt ist die gesamte Dokumentation auf die Anbindung des Spryker B2C Demo Shops ausgerichtet. Bei dessen Verwendung können einige Schwierigkeiten auftreten, deren Ursache weder das FirstSpirit Connect for Spryker Commerce OS-Modul noch die Integration ist. Dennoch werden sie nachfolgend aufgelistet und eine mögliche Lösung skizziert.

Vorschauseite wird im ContentCreator nicht gefunden

Kann der ContentCreator die Vorschauseite nicht finden, ist das Zertifikat der Seite ungültig oder nicht vorhanden. In diesem Fall muss die Seite in einem separaten Browser-Tab geöffnet werden, um das SSL-Zertifikat zu erneuern und die Anzeige der Seite zu erlauben. Anschließend ist die Vorschauseite im ContentCreator wieder sichtbar.

Fehlender RAM bei Composer-Aufrufen

Für PHP existiert standardmäßig ein RAM-Limit, das für die Ausführung von Composer-Aktionen jedoch zu niedrig ist. Aus diesem Grund muss das Limit, das in der Konfigurationsdatei php.ini im Verzeichnis etc/php/7.2/cli definiert ist, deaktiviert werden:

Deaktivierung des RAM-Limits
[...]
set memory_limit=-1
[...]

2. Spryker - Installation und Konfiguration

FirstSpirit dient der Erstellung und Pflege redaktioneller Daten, die in den CaaS übertragen und von diesem persistiert werden. Um die Daten zu integrieren, benötigt Spryker eine Zugriffsmöglichkeit auf den CaaS. Diese wird durch die Spryker-Module firstspirit-preview und firstspirit-caas bereitgestellt, die eine Spryker-seitige Installation und Konfiguration erfordern. Das Modul firstspirit-preview ermöglicht die Darstellung der Storefront im ContentCreator. Die Abfrage der Inhalte aus dem CaaS erfolgt mithilfe des Moduls firstspirit-caas.

Die nachfolgenden Kapitel beschreiben alle notwendigen Schritte für die Installation und die Konfiguration sowie zusätzlich erforderliche Spryker-seitige Erweiterungen.

2.1. Spryker-Module

Sowohl die Abfrage der CaaS-Inhalte durch Spryker als auch ihre Darstellung und Bearbeitung im ContentCreator erfolgt mithilfe verschiedener Spryker-Module. Diese erfordern eine Spryker-seitige Installation sowie eine Erweiterung der Konfiguration. Des Weiteren benötigen sie verschiedene JavaScript- und CSS-Dateien, die Spryker-seitig einzubinden sind.

Die nachfolgenden Kapitel beschreiben die Durchführung der notwendigen Schritte.

2.1.1. Installation der Spryker-Module

Die Pflege von Shop-Inhalten im ContentCreator erfordert die Installation mehrerer Spryker-Module, die in Form von zip-Dateien in der Auslieferung enthalten sind. Sie müssen in einem beliebigen Verzeichnis unterhalb des Spryker-Projektverzeichnisses gespeichert werden, das Composer als weiteres Repository bekannt zu machen ist. Dies geschieht über den im Projektverzeichnis auszuführenden Befehl, der die composer.json-Datei des Spryker-Servers entsprechend erweitert.

Erweiterung der composer.json-Datei
composer config repo.espirit artifact ./PATH-TO-DIRECTORY

Die zu installierenden Spryker-Module nutzen den Namespace ESpirit, der Spryker bekannt zu machen ist. Dafür ist in der Environment-unabhängigen Datei config_default.php im Verzeichnis config/Shared eine Erweiterung der KernelConstants erforderlich:

Erweiterung der KernelConstants
$config[KernelConstants::CORE_NAMESPACES] = [
   'SprykerShop',
   'SprykerEco',
   'Spryker',
   'Generated',
   'ESpirit'
];

Die Session Konstante für die Same Site Cookies muss nach der $config[KernelConstants::CORE_NAMESPACES] gesetzt sein:

Session Konstante
$config[SessionConstants::YVES_SESSION_COOKIE_SAMESITE] = 'None';

Darüber hinaus muss die Domäne zur Whitelist-Konfiguration hinzugefügt werden:

Erweiterung der KernelConstants
$config[KernelConstants::DOMAIN_WHITELIST] = array_merge($trustedHosts, [
    ...
    'demo-spryker.e-spirit.hosting',
]);

Aktivieren Sie SSL in der yaml Datei deploy.dev.yml:

Aktivierung von SSL
docker:

    ssl:
        enabled: true
        redirect: true

Die Installation der Spryker-Module erfolgt anschließend über die nachfolgenden Befehle, die ebenfalls im Spryker-Projektverzeichnis in der angegebenen Reihenfolge auszuführen sind.

Installationsbefehle
composer require e-spirit/firstspirit-caas
composer require e-spirit/firstspirit-preview
composer require e-spirit/firstspirit-preview-navigation
composer require e-spirit/firstspirit-data-state-writer
composer require e-spirit/firstspirit-data-cleanup
composer require e-spirit/firstspirit-data-import
composer require e-spirit/firstspirit-data-inconsistency-check
composer require e-spirit/firstspirit-data-rest-api
composer require e-spirit/firstspirit-cms-data-connector
composer require e-spirit/firstspirit-cms-data-storage

Die Befehle laden die Module aus dem erstellten Repository und installieren sie automatisch.

Der letzte Schritt der Installation entspricht der Generierung der Transfer-Objekte des Data Import-Moduls sowie der Erzeugung des Datenbankschemas, das im CMS Block Data Connector-Modul enthalten ist:

Generierung der Transfer-Objekte und Erzeugung des Datenbankschemas
vendor/bin/console transfer:generate
vendor/bin/console propel:install

2.1.2. Twig-Templates

Das FirstSpirit Connect for Spryker Commerce OS-Modul stellt unterschiedliche Möglichkeiten bereit, auf Shop-Inhalte aus Spryker zuzugreifen und diese in FirstSpirit zu verwenden. Diese Möglichkeiten werden im weiteren Verlauf dieser Dokumentation anhand des mitgelieferten Referenzprojekts in Form von Anwendungsfällen beschrieben.

Besteht der Wunsch, die im Referenzprojekt enthaltenen Absatz- und Seitenvorlagen zu verwenden, setzt dies Spryker-seitig unterschiedliche Twig-Templates voraus.

Die Absätze entsprechen Spryker-seitig verschiedenen Molekülen, Atomen und Organismen, die im Ordner FirstSpiritReferenceComponents zusammengefasst sind. Dieser ist ein Bestandteil der Auslieferung und wird in Form eines weiteren Spryker-Moduls bereitgestellt, das über den folgenden Befehl zu installieren ist:

Installationsbefehl
composer require e-spirit/firstspirit-reference-components

Damit die mit dem Modul zur Verfügung gestellten Komponenten Spryker-seitig einsetzbar sind, muss der ihnen zugehörige Pfad in Spryker bekannt gemacht werden. Dies erfolgt über die Anpassung der Dateien settings.js und tsconfig.json.

Innerhalb der settings.js-Datei im Verzeichnis Spryker-Verzeichnis/frontend ist eine Erweiterung des Kontextes notwendig:

Anpassung der settings.js-Datei
[...]

dirs: [
   join(globalSettings.context, paths.core),
   join(globalSettings.context, './vendor/e-spirit'),
   join(globalSettings.context, paths.eco),
   join(globalSettings.context, paths.project)
],

Der tsconfig.json-Datei im Spryker-Verzeichnis ist ein weiterer Include hinzuzufügen:

Anpassung der tsconfig.json-Datei
[...]

"include": [
   "./vendor/spryker-shop/**/*",
   "./vendor/spryker-eco/**/*",
   "./src/Pyz/Yves/**/*",
   "./vendor/e-spirit/**/*"
],

Das generische Twig-Template fs_molecule_block.twig steuert die Ausgabe der mitgelieferten Moleküle. Es ist ein Bestandteil der in der Auslieferung enthaltenen zip-Datei b2c-demo-shop-extensions-<VERSION>.zip und muss Spryker-seitig unter dem Pfad src/Pyz/Shared/CmsBlock/Theme/default/template abgelegt werden.

Die Spryker-seitige Einbindung der Twig-Templates erfolgt über den nachfolgenden Befehl, der abschließend im Spryker-Projektverzeichnis auszuführen ist.

Einbindung der Twig-Templates
npm run yves

Die FirstSpirit-Vorlagen ermöglichen die Erweiterung bestehender statischer Seiten, Produkt- und Kategorieseiten sowie die Erzeugung dynamischer Inhaltsseiten oder eines Magazins. Das Referenzprojekt enthält dafür die Seitenvorlagen homepage, productpage, categorypage, contentpage und magazine_detail_page. Gleichzeitig müssen Spryker-seitig die folgenden Twig-Templates existieren:

Das Twig-Template home.twig, das unter dem Pfad src/Pyz/Yves/HomePage/Theme/default/views/home zu finden ist, benötigt einige Anpassungen. Diese sind in der Beschreibung statischer Seiten erläutert. Dasselbe gilt für die Twig-Templates pdp.twig, page-layout-catalog.twig und catalog-with-cms-slot.twig, die für die Bearbeitung von Produkt- und Kategorieseite erforderlich sind.

Sie sind in Spryker unter den folgenden Pfaden gespeichert:

  • src/Pyz/Yves/ProductDetailPage/Theme/default/views/pdp

  • src/Pyz/Yves/CatalogPage/Theme/default/templates/page-layout-catalog

  • src/Pyz/Yves/CatalogPage/Theme/default/views/catalog-with-cms-slot

Die übrigen Twig-Templates sind ein Bestandteil der in der Auslieferung enthaltenen zip-Datei und unter den folgenden Pfaden abzulegen:

  • Produkt-Absatz: src/Pyz/Yves/CmsBlockWidget/Theme/default/components/molecules/product-cms-block

  • dynamische Inhaltsseiten: src/Pyz/Shared/Cms/Theme/default/templates/fs-content-page

2.1.3. Import der Slots

Sowohl in Spryker als auch in FirstSpirit basieren Seiten auf einer Struktur unterschiedlicher Komponenten. Zu diesen zählen Spryker-seitig die CMS Slots, die in FirstSpirit durch die Inhaltsbereiche einer Seitenvorlage repräsentiert werden. Die Slots binden CMS Blöcke ein, die jeweils einem FirstSpirit-Absatz entsprechen.

Das Twig-Template home.twig stellt Spryker-seitig eine statische Seite dar und wird im mitgelieferten Referenzprojekt durch die Seitenvorlage homepage abgebildet. Diese besitzt die Inhaltsbereiche fs_slt_2 und fs_slt_3, für die in Spryker die zugehörigen Slots existieren müssen.

Der Import der Slots erfolgt mithilfe der Datei cms_slot.csv, die in Spryker im Verzeichnis /data/import/common/common gespeichert ist. Sie muss durch die gleichnamige Datei aus der Auslieferung ersetzt werden, die zusätzlich die folgenden beiden Zeilen enthält:

Import-Datei cms_slot.csv
template_path,slot_key,content_provider,name,description,is_active
[...]
@HomePage/views/home/home.twig,fs-slt-2,FirstSpiritCmsSlotBlock,Banner,Banner content section for the homepage.,1
@HomePage/views/home/home.twig,fs-slt-3,FirstSpiritCmsSlotBlock,Homepage Content,Homepage main content section.,1

Die Übernahme der neuen Slots erfolgt anschließend über den nachfolgenden Befehl, der im Spryker-Projektverzeichnis auszuführen ist.

Importbefehl
vendor/bin/console data:import cms-slot

2.1.4. Erweiterung der Konfiguration

Die Erstellung und Bearbeitung redaktioneller Inhalte findet FirstSpirit-seitig im ContentCreator statt. In diesem ist mithilfe des Omnichannel Manager die Storefront eingebettet.

Um die Darstellung der Shop-Inhalte aus Spryker im ContentCreator zu ermöglichen, ist eine Erweiterung der umgebungsspezifischen Konfiguration erforderlich. Dafür muss in der Datei config_default-[environment].php im Verzeichnis config/Shared die Definition eines Tokens sowie die Angabe des Hosts und Ports der FirstSpirit-Startseite erfolgen. Außerdem erfordert der Betrieb des CaaS die Angabe einiger Parameter. Diese Parameter sind sowohl für den Produktivbetrieb als auch für den Einsatz des CaaS für die Vorschau notwendig.

Erweiterung der Konfiguration
// ----------- FirstSpirit Preview Configurations
$config[FirstSpiritPreviewConstants::FIRSTSPIRIT_PREVIEW_AUTHENTICATION_INIT_TOKEN] = '<ADD TOKEN>';
$config[FirstSpiritPreviewConstants::FIRSTSPIRIT_PREVIEW_WEB_HOST] = '<ADD FS PREVIEW HOST>';
$config[FirstSpiritPreviewConstants::FIRSTSPIRIT_PREVIEW_CAAS_CONTENT_PAGE_COLLECTION] = '<CAAS COLLECTION>';
$config[FirstSpiritPreviewConstants::FIRSTSPIRIT_PREVIEW_CAAS_CATEGORY_PAGE_COLLECTION] = '<CAAS COLLECTION>';
$config[FirstSpiritPreviewConstants::FIRSTSPIRIT_PREVIEW_CAAS_PRODUCT_PAGE_COLLECTION] = '<CAAS COLLECTION>';
$config[FirstSpiritPreviewConstants::FIRSTSPIRIT_PREVIEW_DISPLAY_BLOCK_RENDER_ERRORS] = true;

// ----------- FirstSpirit Data Import Configurations
$config[FirstSpiritDataImportConstants::FIRSTSPIRIT_DATA_IMPORT_BLOCK_DATA_CAAS_PATH] = '/_aggrs/blocks';
$config[FirstSpiritDataImportConstants::FIRSTSPIRIT_CAAS_REQUEST_PAGESIZE] = <VALUE>;
$config[FirstSpiritDataImportConstants::FIRSTSPIRIT_DATA_IMPORT_URL_TEMPLATE] = '/{locale}/{url}';

// ----------- FirstSpirit CaaS Configurations
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_HOSTNAME_PREVIEW] = '<ADD CAAS HOST>';
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_PORT_PREVIEW] = '<ADD CAAS PORT>';
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_SCHEME_PREVIEW] = '<ADD CAAS SCHEME>';
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_APIKEY_PREVIEW] = '<ADD APIKEY>';
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_DATABASE_PREVIEW] = '<ADD CAAS DATABASE>';

$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_HOSTNAME_ONLINE] = '<ADD CAAS HOST>';
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_PORT_ONLINE] = '<ADD CAAS PORT>';
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_SCHEME_ONLINE] = '<ADD CAAS SCHEME>';
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_APIKEY_ONLINE] = '<ADD APIKEY>';
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_DATABASE_ONLINE] = '<ADD CAAS DATABASE>';

Die config_default-[environment]_[storename].php Dateien können angepasst werden, um verschiedene Konfigurationen für verschiedene Stores zu erstellen:

Erweiterung der Konfiguration für einen spezifischen Store
<?php

use ESpirit\Shared\FirstSpiritCaaS\FirstSpiritCaaSConstants;
use ESpirit\Shared\FirstSpiritDataImport\FirstSpiritDataImportConstants;

$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_DATABASE_PREVIEW] = '<ADD CAAS DATABASE FOR SPECIFIC STORE>';
$config[FirstSpiritCaaSConstants::FIRSTSPIRIT_CAAS_DATABASE_ONLINE] = '<ADD CAAS DATABASE FOR SPECIFIC STORE>';

$config[FirstSpiritDataImportConstants::FIRSTSPIRIT_DATA_IMPORT_URL_TEMPLATE] = '/{locale}/{store}/{url}';

Die Konfiguration FirstSpiritDataImportConstants::FIRSTSPIRIT_DATA_IMPORT_URL_TEMPLATE legt fest, wie die URLs für Inhaltsseiten aus FirstSpirit in Spryker generiert werden. Der Standard ist hierbei //, wobei locale die Sprache der Seite und url die von dem Editor in FirstSpirit hinterlegte URL abbildet. Zusätzlich kann die Variable store verwendet werden, welche das Kürzel für den verwendeten Store beinhaltet. Die Anpassungen an der URL-Struktur müssen im Ausgabekanal der Seitenvorlage für Inhaltsseiten wiedergespiegelt werden.

FirstSpirit Preview Configurations

Der Token dient der Authentifizierung und ist während der FirstSpirit-seitig durchzuführenden Konfiguration als Query-Parameter der externen Vorschau-URL in den ContentCreator-Einstellungen anzugeben. Er kann beliebig definiert werden.

Die Angabe des vollqualifizierten Hosts der FirstSpirit-Startseite (z. B. http://localhost:8000) ist eine Anforderung des noch zu installierenden FsCookieEventDispatcherPlugin. Es nutzt die Information, um die Vorschauanzeige im ContentCreator zu erlauben.

Die Nennungen der CaaS Collections für Inhalts-, Kategorie-, und Produktseiten ermöglichen den Zugriff auf die im Preview CaaS gespeicherten redaktionellen Inhalte und ihre Darstellung im ContentCreator.

Der Error-Parameter ermöglicht die Anzeige von Fehlerausgaben in der Seite. Die Verwendung des Werts true ist daher nur für Dev- und QA-Instanzen sinnvoll.

FirstSpirit Data Import Configurations

Der Pfad dient der Abfrage und Persistierung der im Online CaaS gespeicherten Block-Daten. Er wird vom FsDataImportConsole-Befehl benötigt, der bei einer FirstSpirit-Veröffentlichung den Importer anstößt.

Mithilfe der Pagesize lässt sich die Anzahl der Dokumente definieren, die der CaaS bei einem Request zurückgibt. Der Parameter ist optional und darf einen Wert von 1 bis 100 besitzen. Standardmäßig ist für ihn der Maximalwert von 100 definiert.

FirstSpirit CaaS Configurations

Der CaaS-Host, der zugehörige Port und das zu verwendende Scheme (http oder https) ermöglichen Spryker die Verbindung zum CaaS. Der Zugriff auf die in ihm gespeicherten Daten setzt einen gültigen API Key voraus, der das Leserecht auf das entsprechende Projekt benötigt. Der Name des im CaaS gespeicherten Projekts ist in der Konfigurationsdatei als Wert des Database-Parameters anzugeben.

Weitere Informationen zur Verwendung des CaaS sind in der Content as a Service-Dokumentation enthalten.

Damit die verwendete Klassen FirstSpiritPreviewConstants, FirstSpiritDataImportConstants und FirstSpiritCaaSConstants gefunden werden, sind sie per use-Statement in die Konfigurationsdatei einzubinden:

Einbindung der Klassen
use ESpirit\Shared\FirstSpiritPreview\FirstSpiritPreviewConstants;
use ESpirit\Shared\FirstSpiritDataImport\FirstSpiritDataImportConstants;
use ESpirit\Shared\FirstSpiritCaaS\FirstSpiritCaaSConstants;

2.1.5. Erweiterung des Basis-Templates

Der Omnichannel Manager ermöglicht die Darstellung und Bearbeitung externer Inhalte im ContentCreator, wofür er einige vorschauspezifische Data-Attribute benötigt. Darüber hinaus setzt er Spryker-seitig eine vorschauspezifische JavaScript-Datei voraus, die das FirstSpiritPreview-Modul einbindet.

Die JavaScript-Datei ist dem Twig-Template hinzuzufügen, das für das Basis-Layout aller Shopseiten verantwortlich ist. Im Standardfall handelt es sich dabei um das page-blank.twig-Template, das unter dem Pfad src/Pyz/Yves/ShopUi/Theme/default/templates/page-blank abgelegt ist. In demselben Template muss außerdem die Ermittlung der Data-Attribute durch die Twig-Funktion fsIncludeDataAttributes stattfinden.

Die Anpassung des Twig-Templates erfolgt über den Aufruf der Twig-Funktionen fsIncludeDataAttributes und fsIncludeOcmScript sowie über die Erweiterung der Template-Daten. Der Twig-Funktion fsIncludeOcmScript kann als optionaler Parameter die URL zu einer lokalen Kopie der JavaScript-Datei übergeben werden. Standardmäßig ermittelt sie die Datei aus dem CDN.

Anpassung des Twig-Templates
{% extends template('page-blank', '@SprykerShop:ShopUi') %}

{% block attributes %}
    {{ fsIncludeDataAttributes() }}
{% endblock %}

{% block template %}
   {% set isNewFrontendBuildSupported = true %}

[...]

{% block footerScripts %}
   {% include molecule('check-touch') only %}
      {{ fsIncludeOcmScript() }}
   {{ parent() }}
{% endblock %}

2.2. Anpassungen

Es sind weitere Anpassungen erforderlich, die im folgenden Abschnitt beschrieben werden.

Alle CMS-bezogenen Typen müssen der Datei DataImportConfig im Verzeichnis src/Pyz/Zed/DataImport hinzugefügt werden, um Probleme mit der Aggregationsschleife zu vermeiden.

Erweiterung der DataImportConfig
[...]
public const IMPORT_TYPE_CMS_BLOCK_STORE = 'cms-block-store';
public const IMPORT_TYPE_CMS_BLOCK_CATEGORY_POSITION = 'cms-block-category-position';
public const IMPORT_TYPE_DISCOUNT = 'discount';
[...]

    $customImportTypes = [
        StockAddressDataImportConfig::IMPORT_TYPE_STOCK_ADDRESS,
        static::IMPORT_TYPE_CMS_PAGE,
        static::IMPORT_TYPE_CMS_BLOCK,
        static::IMPORT_TYPE_NAVIGATION,
    ];

[...]

Deaktivieren Sie das Anhängen von Präfixen für CMS-Seiten-URLs, indem Sie die Datei CmsConfig im Verzeichnis src/Pyz/Zed/Cms anpassen.

Anpassung der CmsConfig
[...]

public function appendPrefixToCmsPageUrl(): bool
{
    return false;
}

[...]

Erstellen Sie eine PHP-Datei mit dem Namen CmsSlotGuiCommunicationFactory im neu anzulegenden Verzeichnis src/Pyz/Zed/CmsSlotGui/Communication und eine weitere PHP-Datei mit dem Namen PyzSlotTable im neu anzulegenden Verzeichnis src/Pyz/Zed/CmsSlotGui/Communication/Table mit folgendem Inhalt, um die Backoffice-Tabelle überschreiben zu können.

CmsSlotGuiCommunicationFactory
<?php

/**
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
 */

namespace Pyz\Zed\CmsSlotGui\Communication;

use Pyz\Zed\CmsSlotGui\Communication\Table\PyzSlotTable;
use Spryker\Zed\CmsSlotGui\Communication\Table\SlotTable;
use Spryker\Zed\CmsSlotGui\Communication\CmsSlotGuiCommunicationFactory as SprykerCmsSlotGuiCommunicationFactory;

class CmsSlotGuiCommunicationFactory extends SprykerCmsSlotGuiCommunicationFactory
{
    /**
     * @param int|null $idSlotTemplate
     *
     * @return \Spryker\Zed\CmsSlotGui\Communication\Table\SlotTable
     */
    public function createSlotListTable(?int $idSlotTemplate = null): SlotTable
    {
        return new PyzSlotTable(
            $this->getCmsSlotQuery(),
            $this->getTranslatorFacade(),
            $idSlotTemplate
        );
    }
}
PyzSlotTable
<?php

/**
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
 */

namespace Pyz\Zed\CmsSlotGui\Communication\Table;

use Spryker\Zed\CmsSlotGui\Communication\Table\SlotTable as SprykerSlotTable;

class PyzSlotTable extends SprykerSlotTable
{
    /**
     * @return bool
     */
    protected function isContentProviderColumnVisible(): bool
    {
        if ($this->contentProviderTypesNumber === null) {
            $this->contentProviderTypesNumber = (clone $this->cmsSlotQuery)
                ->select(static::COL_CONTENT_PROVIDER)
                ->distinct()
                ->count();
        }

        return $this->contentProviderTypesNumber > 1;
    }
}

2.3. Plugins

Zusätzlich zur Installation der Spryker-Module ist die Einbindung folgender Plugins erforderlich:

  • FsCookieEventDispatcherPlugin

  • FsTwigExtensionPlugin

  • FirstSpiritPreviewSlotBlockWidgetCmsSlotContentPlugin

  • FirstSpiritDataImportsResourceRoutePlugin

  • FirstSpiritDataCleanupsResourceRoutePlugin

  • FirstSpiritCmsPagesResourceRoutePlugin

FsCookieEventDispatcherPlugin und FsTwigExtensionPlugin

Das FsCookieEventDispatcherPlugin nutzt den in der Konfigurationsdatei config_default-[environment].php angegebenen Hosts der FirstSpirit-Startseite, um die Anzeige der Storefront im ContentCreator zu erlauben. Dafür prüft es, ob Storefront-Abfragen den ebenfalls in der Konfigurationsdatei definierten Token enthalten bzw. ob ein eingeloggter Benutzer existiert. Trifft eine der beiden Optionen zu, setzt das Plugin den Content Security Policy Header und erweitert die Cookie Header.

Das FsTwigExtensionPlugin ermöglicht die FirstSpirit-seitige Pflege von CMS Placeholdern und CMS Blöcken. Dafür greift es auf Informationen zu, die der noch zu installierende CmsController bereitstellt. Die Informationen werden für das Mapping zwischen den in FirstSpirit und den in Spryker gespeicherten Daten benötigt.

Die Einbindung der beiden Plugins erfolgt mithilfe des folgenden Codes, der dem EventDispatcherDependencyProvider im Verzeichnis src/Pyz/Yves/EventDispatcher/EventDispatcherDependencyProvider und dem ShopApplicationDependencyProvider im Verzeichnis src/Pyz/Yves/ShopApplication hinzuzufügen ist.

Erweiterung des EventDispatcherDependencyProvider
use ESpirit\Yves\FirstSpiritPreview\Plugin\EventDispatcher\FsCookieEventDispatcherPlugin;

[...]

protected function getEventDispatcherPlugins(): array
{
   return [
      [...]
      new FsCookieEventDispatcherPlugin(),
   ];
}
Erweiterung des ShopApplicationDependencyProviders
use ESpirit\Yves\FirstSpiritPreview\Plugin\FsTwigExtensionPlugin;
use ESpirit\Yves\FirstSpiritPreview\Plugin\HeadersSecurityExtensionPlugin;
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritCategoryLinkWidget;
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritContentLinkWidget;
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritExternalLinkWidget;
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritProductFlyoutWidget;
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritProductLinkWidget;

[...]

protected function getGlobalWidgets(): array
{
   return [
      [...]
      FirstSpiritCategoryLinkWidget::class,
      FirstSpiritProductLinkWidget::class,
      FirstSpiritContentLinkWidget::class,
      FirstSpiritExternalLinkWidget::class,
      FirstSpiritProductFlyoutWidget::class,
   ];
}

[...]

protected function getApplicationPlugins(): array
{
   return [
      [...]
      new FsTwigExtensionPlugin()
   ];
}
FirstSpiritPreviewSlotBlockWidgetCmsSlotContentPlugin

Das FirstSpiritPreviewSlotBlockWidgetCmsSlotContentPlugin ermöglicht die Ausgabe aller in einem Slot enthaltenen Blöcke. Im Gegensatz zu dem in Spryker enthaltenen CmsSlotBlockWidget, das sich auf die Ausgabe der Spryker-Daten beschränkt, berücksichtigt das Plugin ausschließlich die Informationen aus dem CaaS. Die Einbindung des Plugins erfordert eine Erweiterung des ShopCmsSlotDependencyProviders im Verzeichnis src/Pyz/Yves/ShopCmsSlot.

Erweiterung des ShopCmsSlotDependencyProviders
<?php

namespace Pyz\Yves\ShopCmsSlot;

use ESpirit\Yves\FirstSpiritPreviewSlotBlockWidget\FirstSpiritPreviewSlotBlockWidgetConfig;
use ESpirit\Yves\FirstSpiritPreviewSlotBlockWidget\Plugin\FirstSpiritPreviewSlotBlockWidget\
   FirstSpiritPreviewSlotBlockWidgetCmsSlotContentPlugin;
[...]

class ShopCmsSlotDependencyProvider extends SprykerShopShopCmsSlotDependencyProvider
{
   protected function getCmsSlotContentPlugins(): array
   {
      return [
         CmsSlotBlockConfig::CMS_SLOT_CONTENT_PROVIDER_TYPE
            => new CmsSlotBlockWidgetCmsSlotContentPlugin(),
         FirstSpiritPreviewSlotBlockWidgetConfig::FS_CMS_SLOT_CONTENT_PROVIDER_TYPE
            => new FirstSpiritPreviewSlotBlockWidgetCmsSlotContentPlugin(),
      ];
   }
}
FirstSpiritDataImportsResourceRoutePlugin und FirstSpiritDataCleanupsResourceRoutePlugin

Das FirstSpiritDataImportsResourceRoutePlugin und das FirstSpiritDataCleanupsResourceRoutePlugin stellen jeweils einen API-Endpunkt bereit. Mithilfe dieses Endpunkts kann der FirstSpirit-seitige Deployment-Auftrag den Importer ansprechen.

Das FirstSpiritDataImportsResourceRoutePlugin steuert auf diesem Weg die Übertragung der redaktionellen Inhalte aus dem Online CaaS nach Spryker und ihre dortige Persistierung. Im Gegensatz dazu dient das FirstSpiritDataCleanupsResourceRoutePlugin der Ermittlung und Löschung veralteter Daten in Spryker.

Beide Plugins und das nachfolgende FirstSpiritCmsPagesResourceRoutePlugin sind dem GlueApplicationDependencyProvider hinzuzufügen.

FirstSpiritCmsPagesResourceRoutePlugin

Wird innerhalb des ContentCreators eine neue Seite angelegt, ist parallel die Erzeugung einer CMS Page in Spryker erforderlich. Da der ContentCreator die Storefront anzeigt, wäre die neu erstellte Seite andernfalls nicht in der Vorschau sichtbar. Stattdessen wäre sie bereits gleichzeitig im Live-Stand verfügbar, würde sie erst mit einem Deployment Spryker-seitig erstellt.

Das FirstSpiritCmsPagesResourceRoutePlugin dient der Erzeugung der neuen Seite. Dieses Plugin und die zuvor beschriebenen anderen beiden ResourceRoutePlugins sind dem GlueApplicationDependencyProvider im Verzeichnis src/Pyz/Glue/GlueApplication hinzuzufügen:

Erweiterung des GlueApplicationDependencyProviders
use ESpirit\Glue\FirstSpiritDataRestApi\Plugin\FirstSpiritDataImportsResourceRoutePlugin;
use ESpirit\Glue\FirstSpiritDataRestApi\Plugin\FirstSpiritDataCleanupsResourceRoutePlugin;
use ESpirit\Glue\FirstSpiritDataRestApi\Plugin\FirstSpiritCmsPagesResourceRoutePlugin;

[...]

protected function getResourceRoutePlugins(): array
{
   return [
      [...]
      new FirstSpiritDataImportsResourceRoutePlugin(),
      new FirstSpiritDataCleanupsResourceRoutePlugin(),
      new FirstSpiritCmsPagesResourceRoutePlugin(),
      new FirstSpiritDataStateWriterResourceRoutePlugin(),
      new FirstSpiritDataInconsistencyCheckResourceRoutePlugin(),
   ];
}

2.4. Widgets

Neben den Spryker-Modulen und den Plugins enthält die Auslieferung die nachfolgenden Widgets. Sie ermöglichen die Erweiterbarkeit der im Shop enthaltenen Navigationen sowie den Einsatz der im Referenzprojekt enthaltenen DOM-Verweise und des Shoppable Images. Ausschließlich bei der Verwendung dieser Elemente ist eine Registrierung der Widgets erforderlich.

  • FirstSpiritPreviewContentNavigationWidget

  • FirstSpiritCategoryLinkWidget

  • FirstSpiritProductLinkWidget

  • FirstSpiritContentLinkWidget

  • FirstSpiritExternalLinkWidget

  • FirstSpiritProductFlyoutWidget

FirstSpiritPreviewContentNavigationWidget
Das FirstSpiritPreviewContentNavigationWidget schafft die Möglichkeit, die im Shop enthaltenen Navigationen mit FirstSpirit zu pflegen und um weitere Menüpunkte zu ergänzen. Es ersetzt das bestehende ContentNavigationWidget in Spryker und stellt verschiedene Attribute zur Verfügung, die für die Darstellung der entsprechenden Navigation in der Vorschau erforderlich sind. Dafür ist das in Spryker existierende ContentNavigationWidget unter dem Pfad /src/Pyz/Yves gegen das in der Auslieferung enthaltene FirstSpiritPreviewContentNavigationWidget auszutauschen. Für die Nutzung des FirstSpiritPreviewContentNavigationWidgets ist abschließend eine Registrierung notwendig. Diese erfolgt durch eine Anpassung des TwigDependencyProviders im Verzeichnis /src/Pyz/Yves/Twig/, in dem das ContentNavigationTwigPlugin gegen das FirstSpiritPreviewNavigationWidgetTwigPlugin zu ersetzen ist. Eine Erweiterung des ShopApplicationDependencyProviders wie bei den nachfolgenden Widgets ist für das FirstSpiritPreviewContentNavigationWidget nicht erforderlich.

Anpassung des TwigDependencyProviders
<?php

namespace Pyz\Yves\Twig;

use ESpirit\Yves\FirstSpiritPreviewNavigationWidget\Plugin\Twig\FirstSpiritPreviewNavigationWidgetTwigPlugin;
[...]

class TwigDependencyProvider extends SprykerTwigDependencyProvider
{
   [...]

   protected function getTwigPlugins(): array
   {
      return [
         [...]
         // new ContentNavigationTwigPlugin(),
         new FirstSpiritPreviewNavigationWidgetTwigPlugin(),
      ];
   }

   [...]
}

FirstSpiritCategoryLinkWidget und FirstSpiritProductLinkWidget
Die Widgets FirstSpiritCategoryLinkWidget und FirstSpiritProductLinkWidget dienen der Darstellung redaktioneller DOM-Verweise auf Kategorie- bzw. Produkt-Detailseiten. In beiden Fällen ermittelt das Widget dafür die entsprechende Kategorie bzw. das Produkt anhand eines eindeutigen Identifiers und übergibt das Ergebnis dem Twig-Template, das die Spryker-seitige Darstellung des jeweiligen Verweises steuert. Jedes der beiden Widgets referenziert das ihm zugehörige Twig-Template. Die Twig-Templates werden durch das zuvor installierte FirstSpiritPreview-Modul bereitgestellt.

FirstSpiritContentLinkWidget und FirstSpiritExternalLinkWidget
Das FirstSpiritContentLinkWidget und das FirstSpiritExternalLinkWidget ermöglichen DOM-Verweise auf redaktionelle Inhalte, wobei sich die Art dieser Inhalte jeweils unterscheidet. Das FirstSpiritExternalLinkWidget erlaubt ausschließlich die Referenzierung externer Inhalte. Im Gegensatz dazu dient das FirstSpiritContentLinkWidget der Darstellung interner DOM-Verweise auf dynamische Inhaltsseiten bzw. Magazinartikel, die innerhalb des FirstSpirit-Projekts gepflegt sind. Ein wichtiger Aspekt dabei ist, dass die Ziel-URL interner Verweise auf dynamische Inhaltsseiten von der Ausgabe abhängig sind: Während sich der Verweis im Live-Stand auf die veröffentlichte CMS Page bezieht, muss in der Vorschau die zugehörige Vorschau-URL verwendet werden. Das Widget steuert in beiden Fällen die Ermittlung der jeweils benötigten URL.

FirstSpiritProductFlyoutWidgets
Die Registrierung des FirstSpiritProductFlyoutWidgets ist nur dann erforderlich, wenn das mit der Auslieferung bereitgestellte Shoppable Image im Projekt verwendet wird. Das Widget steuert die Darstellung der Flyouts für die auf dem Shoppable Image verlinkten Produkte.

Registrierung
Die Registrierung der vier Link- sowie des FlyoutWidgets erfolgt mithilfe des folgenden Codes, der dem ShopApplicationDependencyProvider im Verzeichnis src/Pyz/Yves/ShopApplication hinzuzufügen ist.

Erweiterung des ShopApplicationDependencyProviders
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritCategoryLinkWidget;
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritProductLinkWidget;
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritContentLinkWidget;
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritExternalLinkWidget;
use ESpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritProductFlyoutWidget;

[...]

protected function getGlobalWidgets(): array
{
   return [
      [...]
      FirstSpiritCategoryLinkWidget::class,
      FirstSpiritProductLinkWidget::class,
      FirstSpiritContentLinkWidget::class,
      FirstSpiritExternalLinkWidget::class,
      FirstSpiritProductFlyoutWidget::class
   ];
}

2.5. Controller

Das zuvor installierte CmsBlockTwigFunctionPlugin ermöglicht das Mapping zwischen den in FirstSpirit und den in Spryker gespeicherten Inhalten. Dafür setzt es voraus, dass die View-Daten einer Page deren Id und Typ enthalten. Diese Informationen stellen die Controller von Spryker standardmäßig jedoch nicht bereit. Aus diesem Grund ist sowohl für Inhalts- und Kategorieseiten als auch im Fall der Homepage, die einer statischen Seite entspricht, eine Überschreibung der folgenden Controller notwendig:

  • IndexController

  • CatalogController

  • CmsController

  • PreviewController

Die Überschreibung erfolgt durch das Anlegen der zugehörigen Klassen, die alle ein Bestandteil der in der Auslieferung enthaltenen zip-Datei b2c-demo-shop-extensions-<VERSION>.zip sind. Sie müssen in das jeweils zu erzeugende Verzeichnis Controller unterhalb von src/Pyz/Yves/HomePage|CatalogPage|CmsPage kopiert werden.

Existieren die Klassen bereits unter dem für sie genannten Pfad, werden die Controller bereits projektspezifisch überschrieben. In diesem Fall ist jeweils sicherzustellen, dass die View-Parameter entsprechend erweitert werden.

Im Gegensatz zu den übrigen Seiten ist für die Produktseiten die Anpassung des Spryker-seitig bereits existierenden ProductControllers erforderlich. Er ist im Verzeichnis src/Pyz/Yves/ProductDetailPage/Controller/ProductController enthalten und muss um die Definition des Seitentyps und der Product SKU ergänzt werden. Der folgende Code-Ausschnitt zeigt die durchzuführenden Änderungen:

Erweiterung des ProductControllers
<?php
namespace Pyz\Yves\ProductDetailPage\Controller;

[...]
use ESpirit\Shared\FirstSpiritPreview\FirstSpiritPreviewConstants;

class ProductController extends SprykerShopProductController
{
   protected function executeDetailAction(array $productData, Request $request): array
   {
      [...]

       $viewData['cart'] = $quoteTransfer;
       $viewData[FirstSpiritPreviewConstants::VIEW_DATA_PAGE_TYPE_KEY] = FirstSpiritPreviewConstants::PRODUCT_PAGE_TYPE;
       $viewData[FirstSpiritPreviewConstants::VIEW_DATA_PAGE_ID_KEY] = $productData['sku'];

       return $viewData;
   }
}

Zusätzlich zu den genannten Controllern enthält die Auslieferung weitere RenderController, mit denen die Aktualisierung einzelner CMS-Elemente in der Vorschau möglich ist. Sie werden vom FirstSpiritPreviewRoutePlugin angesprochen, das initial nicht in Spryker existiert und daher eine Registrierung in der RouterDependencyProvider-Datei im Verzeichnis Pyz/Yves/Router erfordert. Innerhalb der Datei ist die Methode getRouteProvider wie folgt zu erweitern.

Erweiterung der Methode getRouteProvider
use ESpirit\Yves\FirstSpiritPreview\Plugin\Route\FirstSpiritPreviewRoutePlugin;

[...]
protected function getRouteProvider(): array
{
   return [
      [...]
      new FirstSpiritPreviewRoutePlugin()
   ];
}

Für die Aktivierung von Gateway-Routing, ist eine Anpassung der Datei RouterConfig im Verzeichnis src/Pyz/Zed/Router erforderlich.

RouterConfig
public function getControllerDirectories(): array
{
   [...]
   $controllerDirectories[] = sprintf('%s/e-spirit/*/src/*/Zed/*/Communication/Controller/', APPLICATION_VENDOR_DIR);

   return array_filter($controllerDirectories, 'glob');
}

2.6. Hauptnavigation

Der Spryker B2C Demo Shop enthält standardmäßig unterschiedliche Navigationen, die sich Spryker-seitig erzeugen und bearbeiten lassen. Die mit dem FirstSpirit Connect for Spryker Commerce OS-Modul realisierte Integration bietet die Möglichkeit, diese Navigationen auch mit FirstSpirit zu pflegen und um weitere Menüpunkte zu ergänzen.

Innerhalb des Referenzprojekts ist die Funktionalität exemplarisch für die Hauptnavigation umgesetzt. Ihre Verwendung setzt die bereits beschriebene Referenzierung des FirstSpiritPreviewContentNavigationWidgets, die Erzeugung eines Platzhalters sowie die Ergänzung einer Preview ID voraus.

Der zu erzeugende Platzhalter entspricht einem weiteren Menüpunkt. Dieser ist für die Darstellung der Navigation in der Vorschau erforderlich und der navigation-header.twig-Datei im Verzeichnis src/Pyz/Yves/ShopUi/Theme/default/components/molecules/navigation-header hinzuzufügen:

Anpassung der navigation-header.twig-Datei
[..]
<ul class="menu {{ menuClass }} grid grid--center grid--no-wrap">
   {% for node in data.nodes %}
      [..]
   {% endfor %}

   {% if isFsPreview() %}
      <li class="fs-navigation-extension"
         style="padding-left: 1rem; transform: translate(0,15% );">
      </li>
   {% endif %}
</ul>
[..]

Für die Darstellung der Hauptnavigation in der Vorschau ist darüber hinaus eine Preview ID erforderlich. Ihre Definition erfolgt in der navigation-multilevel-node.twig-Datei im Verzeichnis src/Pyz/Yves/ShopUi/Theme/default/components/molecules/navigation-multilevel-node.

Anpassung der navigation-multilevel-node.twig-Datei
[...]

{% block attributes %}
   {% if isFsPreview() and data.node.previewId is defined and data.node.previewId is not empty %}
      data-preview-id="{{ data.node.previewId }}" style="min-height: unset;"
   {% endif %}
{% endblock %}

Fügen Sie den folgenden Code dem Atom hinzu, um die Twig Fehlermeldung in der navigation-list.twig Datei zu beheben:

Anpassung der navigation-list.twig-Datei
{% block body %}
   [...]
   {% import _self as component %}
   {% block url %}
   [...]
{% endblock %}

Unter Umständen ist nach den vorgenommenen Änderungen eine Leerung des Caches für die Twig-Templates sowie eine Neuerzeugung des Frontends notwendig.

2.7. Query Container

Das zuvor installierte Cms Block Data Connector-Modul erzeugt eine Zed-Tabelle. In dieser Tabelle werden während des Imports die aus dem Online CaaS ermittelten redaktionellen Inhalte gespeichert. Die Persistierung der CMS Blöcke erfolgt in einer weiteren Tabelle.

Da die CMS Blöcke keine Placeholder enthalten, werden sie von Spryker standardmäßig nicht publiziert. Aus diesem Grund ist es notwendig, den CmsBlockStorageQueryContainer zu überschreiben und damit das Spryker-seitige Standardverhalten zur Publizierung von CMS Blöcken anzupassen. Die Überschreibung des Query Containers erfolgt durch das Anlegen der Klasse CmsBlockStorageQueryContainer.php. Sie ist ein Bestandteil der in der Auslieferung enthaltenen zip-Datei b2c-demo-shop-extensions-<VERSION>.zip und ist in das zu erzeugenden Verzeichnis src/Pyz/Zed/CmsBlockStorage/Persistence zu kopieren.

2.8. Technischer Benutzer

Die mit dem FirstSpirit Connect for Spryker Commerce OS-Modul realisierte Integration sieht FirstSpirit-seitig lediglich die Erzeugung und Pflege der redaktionellen Inhalte sowie ihre Publizierung in Form von JSON-Objekten vor. Die Einbindung dieser Inhalte und die Erzeugung der Vorschau findet jedoch weiterhin Spryker-seitig statt.

Im Vorschaufall ermittelt FirstSpirit die aktuelle Ansicht einer Seite in der Storefront und zeigt sie mithilfe des Omnichannel Managers im ContentCreator an. Für die Integration der redaktionellen Inhalte in den Shop, importiert Spryker sie aus dem Online CaaS und persistiert sie in seinem internen Datensystem.

Da sowohl die Vorschau als auch der Importprozess per Authentifizierung geschützt ist, muss in der Projekt-Komponente des FirstSpirit Connect for Spryker Commerce OS-Moduls ein technischer Benutzer angegeben werden. Dieser entspricht einem Customer, der wiederum einem Zed-User zugewiesen ist. Die Zuweisung lässt sich im Menü Users Control  User über den Button Assign Customers durchführen.

Eine genauere Beschreibung der für die Zuweisung notwendigen Schritte ist in den Kapiteln Assigning Customers und Previewing a Page der Spryker-Dokumentation enthalten.

2.9. Import-Befehl

Die Integration der FirstSpirit-seitig erstellten bzw. gepflegten Inhalte in den Shop erfolgt durch Spryker. Dafür importiert Spryker die Daten aus dem Online CaaS und persistiert sie in seinem Datensystem. Die Übertragung der Informationen muss bei jeder FirstSpirit-Veröffentlichung stattfinden, die aus diesem Grund jedes Mal einen Spryker-seitigen Import-Befehl anstößt.

Der Befehl weist den Importer an, die im Online CaaS gespeicherten Block-Daten zu importieren. Dabei nutzt er den in der Konfigurationsdatei config_default-[environment].php angegebenen FirstSpirit Data Import Block CaaS Path. Mithilfe dieses Pfads greift der Importer auf die CaaS-Aggregation zu, die während der FirstSpirit-Veröffentlichung erzeugt wird.

Die Import-Befehle müssen Spryker-seitig in den getConsoleCommands registriert werden. Dafür ist die folgende Erweiterung der ConsoleDependencyProvider.php-Datei im Verzeichnis src/Pyz/Zed/Console erforderlich:

Erweiterung der getConsoleCommands
use ESpirit\Zed\FirstSpiritDataImport\Communication\Console\FsDataImportConsole;
use ESpirit\Zed\FirstSpiritDataImport\Communication\Console\FsStoreDataImportConsole;

[...]

$commands = [
   // Default commands
   [...]

   new DataImportConsole(DataImportConsole::DEFAULT_NAME . ':' . DataImportConfig::IMPORT_TYPE_CMS_BLOCK_STORE),
   new DataImportConsole(DataImportConsole::DEFAULT_NAME . ':' . DataImportConfig::IMPORT_TYPE_CMS_BLOCK_CATEGORY_POSITION),
   new DataImportConsole(DataImportConsole::DEFAULT_NAME . ':' . DataImportConfig::IMPORT_TYPE_DISCOUNT),

   [...]

   // FirstSpirit Data importers
   new FsDataImportConsole(FsDataImportConsole::DEFAULT_NAME),
   new FsStoreDataImportConsole(FsStoreDataImportConsole::DEFAULT_NAME),
];

Damit die Blöcke für Kategorieseiten importiert werden können, muss der Inalt der DataImportBusinessFactory.php-Dateo im Verzeichnis src/Pyz/Zed/DataImport/Business angepasst werden:

Erweiterung der DataImportBusinessFactory
[...]
use Pyz\Zed\DataImport\Business\Model\CmsBlock\CmsBlockWriterStep;
use Pyz\Zed\DataImport\Business\Model\CmsBlockCategoryPosition\CmsBlockCategoryPositionWriterStep;
use Pyz\Zed\DataImport\Business\Model\CmsBlockStore\CmsBlockStoreWriterStep;
[...]

   public function getDataImporterByType(DataImportConfigurationActionTransfer $dataImportConfigurationActionTransfer): ?DataImporterInterface
   {
      switch ($dataImportConfigurationActionTransfer->getDataEntity()) {
         [...]
         case DataImportConfig::IMPORT_TYPE_CMS_BLOCK_STORE:
               return $this->createCmsBlockStoreImporter($dataImportConfigurationActionTransfer);
         case DataImportConfig::IMPORT_TYPE_CMS_BLOCK_CATEGORY_POSITION:
               return $this->createCmsBlockCategoryPositionImporter($dataImportConfigurationActionTransfer);
         case DataImportConfig::IMPORT_TYPE_DISCOUNT_AMOUNT:
               return $this->createDiscountAmountImporter($dataImportConfigurationActionTransfer);
         [...]
      }
   }


   [...]

   /**
    * @param \Generated\Shared\Transfer\DataImportConfigurationActionTransfer $dataImportConfigurationActionTransfer
    *
    * @return \Spryker\Zed\DataImport\Business\Model\DataImporterInterface|\Spryker\Zed\DataImport\Business\Model\DataSet\DataSetStepBrokerAwareInterface
    */
   protected function createCmsBlockCategoryPositionImporter(DataImportConfigurationActionTransfer $dataImportConfigurationActionTransfer)
      {
      $dataImporter = $this->getCsvDataImporterFromConfig(
      $this->getConfig()->buildImporterConfigurationByDataImportConfigAction($dataImportConfigurationActionTransfer)
      );

      $dataSetStepBroker = $this->createTransactionAwareDataSetStepBroker(CmsBlockCategoryPositionWriterStep::BULK_SIZE);
      $dataSetStepBroker->addStep(new CmsBlockCategoryPositionWriterStep());
      $dataImporter->addDataSetStepBroker($dataSetStepBroker);

      return $dataImporter;
   }

   [...]

2.10. Synchronisation

Die in FirstSpirit gepflegten redaktionellen Inhalte werden während des Deployments mithilfe des Importers aus dem Online CaaS abgefragt. Der Importer überträgt die Daten nach Spryker und persistiert sie Backend-seitig in dessen Datensystem. Die Anzeige der Daten im Live-Stand erfordert zusätzlich ihre Übertragung nach Yves. Die Übertragung der Daten erfordert die Registrierung eines Event Subscribers, verschiedener Queues und eines Message Processors.

Nähere Informationen sind im Kapitel Publish and Synchronization der Spryker Dokumentation enthalten.

Die Registrierung des EventSubscribers erfolgt mithilfe des folgenden Codes, der dem EventDependencyProvider im Verzeichnis Pyz/Zed/Event hinzuzufügen ist.

EventDependencyProvider
use ESpirit\Zed\FirstSpiritCmsDataStorage\Communication\Plugin\Event\Subscriber\FirstSpiritCmsDataStorageEventSubscriber;

[...]

class EventDependencyProvider extends SprykerEventDependencyProvider
{
   [...]

   public function getEventSubscriberCollection()
   {
      $eventSubscriberCollection = parent::getEventSubscriberCollection();

      /**
      * Storage Events
      */
      [...]
      $eventSubscriberCollection->add(new FirstSpiritCmsDataStorageEventSubscriber());

      /**
      * Search Events
      */
      [...]

      return $eventSubscriberCollection;
   }
}

Die Registrierung der Queues setzt die folgende Anpassung der RabbitMqConfig-Datei im Verzeichnis src/Pyz/Client/RabbitMq voraus:

RabbitMqConfig
<?php
namespace Pyz\Client\RabbitMq;

use ESpirit\Shared\FirstSpiritCmsDataStorage\FirstSpiritCmsDataStorageConfig;
[...]

class RabbitMqConfig extends SprykerRabbitMqConfig
{
   [...]

   protected function getPublishQueueConfiguration(): array
   {
      return [
         PublisherConfig::PUBLISH_QUEUE => [
            [...]
         ],
         [...]
         FirstSpiritCmsDataStorageConfig::PUBLISH_CMS_PAGE_DATA_CONNECTOR,
         FirstSpiritCmsDataStorageConfig::PUBLISH_CMS_BLOCK_DATA_CONNECTOR
      ];
   }

   protected function getSynchronizationQueueConfiguration(): array
   {
      return [
         [...]
         FirstSpiritCmsDataStorageConfig::CMS_PAGE_DATA_CONNECTOR_SYNC_STORAGE_QUEUE,
         FirstSpiritCmsDataStorageConfig::CMS_BLOCK_DATA_CONNECTOR_SYNC_STORAGE_QUEUE
      ];
   }

   [...]
}

Das Trigger-Plugin muss der Datei EventBehaviorDependencyProvider im Verzeichnis src/Pyz/Zed/EventBehavior hinzugefügt werden.

EventBehaviorDependencyProvider
<?php

namespace Pyz\Zed\EventBehavior;

use ESpirit\Zed\FirstSpiritCmsDataStorage\Communication\Plugin\Event\FirstSpiritCmsBlockDataEventResourceQueryContainerPlugin;
use ESpirit\Zed\FirstSpiritCmsDataStorage\Communication\Plugin\Event\FirstSpiritCmsDataEventResourceQueryContainerPlugin;
[...]

class EventBehaviorDependencyProvider extends SprykerEventBehaviorDependencyProvider
{
   protected function getEventTriggerResourcePlugins()
   {
      return [
         [...]
         new FirstSpiritCmsDataEventResourceQueryContainerPlugin(),
         new FirstSpiritCmsBlockDataEventResourceQueryContainerPlugin(),
      ];
   }
}

Um das Auslösen von Ereignissen aus der GLUE-Anwendung heraus zu ermöglichen, muss das Dispatcher-Plugin der Datei EventDispatcherDependencyProvider im Verzeichnis src/Pyz/Zed/EventDispatcher hinzugefügt werden.

EventDispatcherDependencyProvider
[...]

protected function getBackendGatewayEventDispatcherPlugins(): array
{
   return [
      [...]
      new EventBehaviorEventDispatcherPlugin(),
   ];
}

Das Sync-Plugin muss der Datei SynchronizationDependencyProvider im Verzeichnis src/Pyz/Zed/Synchronization hinzugefügt werden.

SynchronizationDependencyProvider
<?php

namespace Pyz\Zed\Synchronization;

use ESpirit\Zed\FirstSpiritCmsDataStorage\Communication\Plugin\Synchronization\FirstSpiritCmsBlockDataSynchronizationDataBulkPlugin;
use ESpirit\Zed\FirstSpiritCmsDataStorage\Communication\Plugin\Synchronization\FirstSpiritCmsDataSynchronizationDataBulkPlugin;
[...]

class SynchronizationDependencyProvider extends SprykerSynchronizationDependencyProvider
{
   protected function getSynchronizationDataPlugins(): array
   {
      return [
         [...]
         new FirstSpiritCmsDataSynchronizationDataBulkPlugin(),
         new FirstSpiritCmsBlockDataSynchronizationDataBulkPlugin(),
      ];
   }

   [...]
}

Die Registrierung des für die Queues notwendigen Event Subscribers macht eine Anpassung des QueueDependencyProviders im Verzeichnis Pyz/Zed/Queue erforderlich:

QueueDependencyProvider
<?php
namespace Pyz\Zed\Queue;

use ESpirit\Shared\FirstSpiritCmsDataStorage\FirstSpiritCmsDataStorageConfig;

[...]

class QueueDependencyProvider extends SprykerDependencyProvider
{
   protected function getProcessorMessagePlugins(Container $container)
   {
      return [
         [...]
         FirstSpiritCmsDataStorageConfig::PUBLISH_CMS_PAGE_DATA_CONNECTOR => new EventQueueMessageProcessorPlugin(),
         FirstSpiritCmsDataStorageConfig::PUBLISH_CMS_BLOCK_DATA_CONNECTOR => new EventQueueMessageProcessorPlugin(),
         FirstSpiritCmsDataStorageConfig::CMS_PAGE_DATA_CONNECTOR_SYNC_STORAGE_QUEUE => new SynchronizationStorageQueueMessageProcessorPlugin(),
         FirstSpiritCmsDataStorageConfig::CMS_BLOCK_DATA_CONNECTOR_SYNC_STORAGE_QUEUE => new SynchronizationStorageQueueMessageProcessorPlugin(),
      ];
   }
}

3. FirstSpirit - Installation und Konfiguration

Für die Verwendung der Funktionalitäten des FirstSpirit Connect for Spryker Commerce OS-Moduls ist FirstSpirit-seitig die Installation und Konfiguration unterschiedlicher Komponenten erforderlich. Die folgenden Unterkapitel erläutern die dafür notwendigen Schritte.

3.1. Konfiguration der Projekt-Komponente

Für den Einsatz des FirstSpirit Connect for Spryker Commerce OS-Moduls ist eine projektspezifische Konfiguration notwendig. Diese wird über die Projekt-Komponente vorgenommen, die dem mitgelieferten Referenzprojekt bereits hinzugefügt ist.

Zur Nutzung des FirstSpirit Connect for Spryker Commerce OS-Moduls muss außerdem das Content as a Service-Modul konfiguriert werden. Die dafür notwendigen Schritte sind in der Content as a Service-Dokumentation beschrieben.

Innerhalb des Referenzprojekts ist in der Projekt-Komponente des CaaS für die Mediennutzung die Generierung der Medien in den CaaS definiert. Diese Konfiguration ist explizit nicht im Produktivbetrieb einzusetzen. Für den Produktivbetrieb muss die Mediennutzung auf die Verwendung eines CDNs umgestellt werden.

Öffnen Sie für die Konfiguration der Projekt-Komponente den ServerManager und wählen Sie den Bereich Projekt-Eigenschaften  Projekt-Komponenten.

projectcomponents
Abbildung 4. Server-Eigenschaften - Projekt-Komponenten

Im Hauptpanel ist eine Liste aller bereits vorhandenen Projekt-Komponenten zu sehen. Selektieren Sie den Eintrag FirstSpirit Connect for Spryker Commerce OS for FirstSpirit Commerce OS Project Configuration und öffnen Sie den zugehörigen Konfigurationsdialog über Konfigurieren.

Der Dialog gliedert sich in die Tabs Allgemein, Vorschau, Veröffentlichung und YouTube:

Allgemein

Innerhalb des Reiters Allgemein sind die Storefront Basis URL und die Glue-API Basis URL anzugeben. Sie müssen dem FirstSpirit-Server bekannt sein, um eine Verbindung zu Spryker herstellen und Daten abfragen zu können.

Außerdem besteht die Möglichkeit, benutzerdefinierte Werte für den Connection-Timeout und den Socket-Timeout anzugeben. Ohne Angabe von Werten werden bei der Kommunikation mit der Glue-API die Defaultwerte von 60 Sekunden für den Socket-Timeout und 10 Sekunden für den Connection-Timeout verwendet.

pcomp general
Abbildung 5. Projekt-Komponente - Allgemein

Vorschau

Innerhalb des Reiters Vorschau wird zunächst der Login-Pfad benötigt. Das entsprechende Feld enthält vorausgefüllt den Default-Wert /firstspirit_login_check, der sich bei Bedarf anpassen lässt.

Des Weiteren sind in diesem Reiter die Login-Daten eines technischen Benutzers einzutragen. Dieser muss dem Customer entsprechen, der während der Spryker-seitig auszuführenden Schritte definiert wurde. Er dient der Spryker-seitigen Abfrage der Storefront, die mithilfe des Omnichannel Managers im ContentCreator eingebunden wird.

pcomp preview
Abbildung 6. Projekt-Komponente - Vorschau

Veröffentlichung

Der Reiter Veröffentlichung enthält jeweils eine Liste aller im Projekt verfügbaren Gruppen und Voll-Deployment-Aufträge. Er ermöglicht die Bereitstellung des selektierten Deployment-Auftrags im Aktionen-Menü des ContentCreators für die im Reiter aktivierten Gruppen. Das Aktionen-Menü enthält für die Ausführung des Auftrags den Menüpunkt Veröffentlichung. Für Gruppen, denen die Ausführung des Auftrags nicht erlaubt ist, ist der Eintrag sichtbar, aber deaktiviert.

Innerhalb des mitgelieferten Referenzprojekts kann dem ChiefEditor auf diesem Weg beispielsweise die Ausführung des Voll-Deployments ermöglicht werden.

Darüber hinaus verwenden der Freigabe- und der Lösch-Arbeitsablauf den an dieser Stelle selektierten Auftrag, wenn zusätzlich zur Freigabe bzw. Löschung einer Seite die Publikation des gesamten Projekts angestoßen werden soll.

Für Server- und Projektadministratoren ist die Ausführung des Voll-Deployments standardmäßig erlaubt, unabhängig von der Konfiguration innerhalb des Reiters.

pcomp deployment
Abbildung 7. Projekt-Komponente - Veröffentlichung

YouTube

Das bereitgestellte Referenzprojekt enthält einen Shoppable Video-Absatz. Dieser ermöglicht die Anzeige und Referenzierung von Produkten zu definierten Zeitpunkten in einem YouTube-Video. Die Verwendung des Absatzes setzt einen Google API Key voraus, der an dieser Stelle einzutragen ist.

Darüber hinaus lassen sich kommasepariert ein oder mehrere Channel-Ids angeben. Sobald das Feld eine Id enthält, zeigt die Video-Auswahl ein Dropdown an. Dieses erlaubt die Referenzierung eines YouTube-Videos aus einem spezifischen Channel.

pcomp youtube
Abbildung 8. Projekt-Komponente - YouTube

3.2. Hinzufügen der Web-Komponenten

Für den ContentCreator wird eine Web-Komponente benötigt, die dem mitgelieferten Referenzprojekt bereits hinzugefügt ist. Sie ist standardmäßig global im ServerManager im Bereich Server-Eigenschaften  Web-Applikationen installiert. In diesem Fall sind alle für die Web-Komponente erforderlichen Installations- und Konfigurationsschritte bereits seitens der Crownpeak Technology GmbH durchgeführt.

Alternativ ist jedoch auch eine Installation der Web-Komponente in den Projekt-Eigenschaften möglich. Ausschließlich in diesem Fall muss sie noch auf einem aktiven Webserver installiert werden. Öffnen Sie hierfür den ServerManager und wählen Sie den Bereich Projekt-Eigenschaften  Web-Komponenten.

Innerhalb des Hauptpanels sind verschiedene Registerkarten zu sehen, in denen jeweils eine Liste der bereits vorhandenen Web-Komponenten sichtbar ist. Diese Liste enthält für die Vorschau und den ContentCreator die FirstSpirit Connect for Spryker Commerce OS for Spryker Commerce OS Web App. Im ContentCreator-Tab ist darüber hinaus die FirstSpirit ThirdPartyPreview WebApp und optional die BasicWorkflows_ContentCreator_Library hinzugefügt (vgl. Abbildung Web-Komponenten in den Projekt-Eigenschaften). Die Web-Komponente der BasicWorkflows ist ausschließlich bei der Nutzung der Arbeitsabläufe erforderlich.

Selektieren Sie in beiden Registerkarten einen Webserver über die Auswahlbox und starten Sie die Installation jeweils über den Button Installieren. Nach der erfolgreichen Installation öffnet sich ein Dialog, in welchem die Aktivierung des Webservers zu bestätigen ist.

Detaillierte Informationen zum Hinzufügen von Web-Komponenten finden Sie in der FirstSpirit Dokumentation für Administratoren.

webcomponents
Abbildung 9. Web-Komponenten in den Projekt-Eigenschaften

3.3. Definition der externen Vorschau-URL

Durch die Verwendung des Omnichannel Managers stellt der ContentCreator externe Inhalte aus Spryker dar, auf die der Omnichannel Manager eine Zugriffsmöglichkeit benötigt. In den ContentCreator-Eigenschaften ist daher die Vorschau-URL der Spryker-Storefront anzugeben. Da die Angabe stets projektspezifisch ist, existiert für sie innerhalb des Referenzprojekts keine Standardkonfiguration.

Öffnen Sie für die Eingabe den Bereich Projekt-Eigenschaften  ContentCreator innerhalb des ServerManagers und tragen Sie in dem Feld Externe Vorschau-URL die URL der Storefront mit der folgenden Syntax an:

https://[STOREFRONT_HOST_DOMAIN]/en/?firstSpiritPreview=[PREVIEW_INIT_TOKEN]

Der für den Queryparameter firstSpiritPreview anzugebende Token muss mit dem Authentifizierungstoken übereinstimmen, der während der Spryker-seitig durchzuführenden Konfiguration definiert wurde. Er ist in der Datei config_default-[environment].php im Verzeichnis config/Shared gespeichert.

previewurl
Abbildung 10. Externe Vorschau-URL

3.4. Konvertierungsregel

Die Definition der an den CaaS zu übertragenden Daten findet im noch anzulegenden Ausgabekanal statt. Die Verwendung bestimmter Sonderzeichen könnte zu invaliden JSON-Objekten führen. Aus diesem Grund muss eine Konvertierungsregel angelegt werden, um potentielle Fehler zu vermeiden.

Es empfiehlt sich, eine neue Konvertierungsregel anzulegen, anstatt eine bestehende zu bearbeiten. Erzeugen Sie hierfür eine Textdatei in Ihrem Dateisystem und fügen Sie dieser den folgenden Inhalt hinzu:

Konvertierungsregel
0x22="\""
[convert]
0x3c="&lt;"
0x3e="&gt;"
0x22="&#34;"
0x26="&amp;"
0x27="&#39;"

Öffnen Sie anschließend den ServerManager und selektieren Sie den Punkt Server-Eigenschaften  Konvertierungs-Regeln. Im Hauptpanel ist eine Liste der bereits existierenden Konvertierungsregeln zu sehen. Wählen Sie nach dem Klicken auf Hinzufügen die zuvor erstellte Textdatei aus Ihrem Dateisystem aus und bestätigen Sie die Auswahl mit Öffnen. Die Liste im Hauptpanel wird daraufhin um die neue Regel ergänzt, die dem zu erstellenden Ausgabekanal zuzuordnen ist.

Weitere Informationen finden Sie in der FirstSpirit Dokumentation für Administratoren.

3.5. Ausgabekanal

Zusätzlich zu den bereits vorhandenen Ausgabekanälen eines Projekts wird ein weiterer XML-Kanal benötigt. Dieser muss für leere Projekte manuell angelegt werden, ist innerhalb des mitgelieferten Referenzprojekts FirstSpirit Connect for Spryker Commerce OS Reference Project jedoch bereits enthalten.

Der Ausgabekanal wurde im ServerManager unter dem Punkt Projekt-Eigenschaften  Vorlagensätze angelegt und besitzt folgende Konfiguration:

templateset
Abbildung 11. Ausgabekanal

In der gleichnamigen Auswahlbox muss die zuvor erzeugte Konvertierungsregel ausgewählt werden.

Der Ausgabekanal ist aktiviert und steht somit im Projekt zur Verfügung. Er dient der Definition der zu übertragenden Inhalte, die während der Generierung in Nachrichten zusammengefasst und an den CaaS übermittelt werden.

3.6. Auflösungen

Das Referenzprojekt FirstSpirit Connect for Spryker Commerce OS Reference Project besitzt unterschiedliche Absätze, mit denen sich auf den verschiedenen Seiten Bilder einbinden lassen. Die Bilder sollen durch den Redakteur auf einen bestimmten Bildausschnitt zugeschnitten werden können. Diese Funktionalität wird über die Angabe einer Auflösung aktiviert.

Für das Referenzprojekt werden die Auflösungen CONTENT_IMAGE, BANNER_IMAGE and MAGAZINE_ARTICLE_BANNER benötigt. Sie sind bereits innerhalb des ServerManagers im Bereich Projekt-Eigenschaften  Auflösungen angelegt und an den entsprechenden Stellen angegeben.

resolutions
Abbildung 12. Auflösungen

3.7. Generierungsauftrag - Vollgenerierung

Die Freigabe von Inhalten sieht standardmäßig keine Aktualisierung des Online CaaS und keine Datenübertragung nach Spryker vor. Sie umfasst stattdessen lediglich den FirstSpirit-Freigabeprozess, der sich beispielsweise durch die Benutzung des Freigabe-Arbeitsablaufs der BasicWorkflows abbilden lässt. Eine Aktualisierung des Online CaaS sowie eine Datenübertragung nach Spryker findet erst im Rahmen einer Veröffentlichung statt.

Die Veröffentlichung freigegebener redaktioneller Inhalte erfolgt durch die Ausführung eines CaaS-Auftrags. Das Referenzprojekt besitzt dafür den Auftrag Spryker Deployment, der innerhalb des ServerManagers im Bereich Projekt-Eigenschaften  Auftragsverwaltung angelegt ist. Er lässt sich mithilfe der im ContentCreator verfügbaren Aktion Veröffentlichung starten und enthält die folgenden Aktionen:

deploy actions
Abbildung 13. Aktionen der Vollgenerierung

Der Auftrag führt eine Vollgenerierung aus und überträgt die Daten in den Online CaaS, der sie Spryker für den Import bereitstellt. Dabei dienen die Aktionen Initialize CaaS Generation, CaaS Generate, CaaS Cleanup und Finalize CaaS Generation der Befüllung des Online CaaS. Sie sind in der Content as a Service-Dokumentation beschrieben.

Die Aktionen Execute Publish Media to CDN, Setup CaaS Blocks Aggregations, Trigger Spryker Import, Trigger Fetch Spryker Logs, Trigger Spryker Cleanup und Send Result Mail erweitern den Auftrag und sind in den nachfolgenden Unterkapiteln beschrieben.

Die Aktion Send Result Mail verschickt im Fehlerfall eine E-Mail mit allen relevanten Informationen an einen zu definierenden Empfänger. Dessen E-Mail-Adresse ist dafür im Feld eMail-Verteiler in den Eigenschaften des Auftrags anzugeben.

Darüber hinaus muss es der Gruppe ChiefEditors innerhalb des Referenzprojekts möglich sein, die Vollgenerierung auszuführen. Dafür muss der Gruppe die Interaktive Ausführung in den Eigenschaften des Auftrags erlaubt werden. In dem mitgelieferten Auftrag ist diese Einstellung bereits vorgenommen.

deploy groups
Abbildung 14. Eigenschaften des Auftrags

3.7.1. Execute Publish Media to CDN

Anders als die mit FirstSpirit erstellten Inhalte, erfolgt die Übertragung der freigegebenen Medien nicht in den CaaS, sonden standardmäßig in ein von der Crownpeak Technology GmbH bereitgestelltes CDN. Der Auftrag enthält dafür die Skript-Aktion Execute Publish Media to CDN.

Execute Publish Media to CDN
import de.espirit.firstspirit.access.AdminService;

String SCHEDULER_NAME = "Media Deployment";

connection = context.getConnection();
adminService = connection.getService(AdminService.class);

scheduleStorage = adminService.getScheduleStorage();
scheduleEntry = scheduleStorage.getScheduleEntry(context.getProject(), SCHEDULER_NAME);

if(scheduleEntry != null) {
   control = scheduleEntry.execute();
   control.awaitTermination();
   isSuccessful =
      control.state.state.equals(de.espirit.firstspirit.access.schedule.RunState.SUCCESS);
   if(!isSuccessful){
      context.logWarning(SCHEDULER_NAME + " Completed with errors!");
   }
   context.logInfo("Schedule Entry executed...");
} else {
   context.logError("Could not find schedule entry with name" + SCHEDULER_NAME);
}

Das Skript ruft den Auftrag für die Mediengenerierung auf, der ebenfalls im bereitgestellten Referenzprojekt enthaltenen ist. Es enthält dafür die Variable SCHEDULER_NAME, die als Wert den Namen des Auftrags besitzt. Ändert sich der Name, ist er auch an dieser Stelle entsprechend anzupassen.

3.7.2. Setup CaaS Blocks Aggregations

Standardmäßig speichert der CaaS die aus FirstSpirit übertragenden Inhalte seitenbasiert ab und liefert sie ebenso aus. Die Verarbeitung und Persistierung redaktioneller Inhalte erfolgt in Spryker jedoch auf der Grundlage von CMS Blöcken, die jeweils einem FirstSpirit-Absatz entprechen. Um diese Diskrepanz aufzulösen, müssen die im Online CaaS gespeicherten Daten daher vor dem Import entsprechend aufbereitet werden. Aus diesem Grund ist ausschließlich allen Collections des Online CaaS eine Aggregation hinzuzufügen. Für den Preview CaaS ist diese Anpassung nicht notwendig, da die Informationen im Vorschaufall direkt von ihm bezogen werden und keine Verarbeitung in Spryker stattfindet.

Der Auftrag enthält für die Erzeugung der Aggregationen die Skript-Aktion Setup CaaS Blocks Aggregations.

Setup CaaS Blocks Aggregations
#! executable-class
com.espirit.ecom.contentconnect.spryker.module.caas.BlocksAggregationSetupExecutable

Das Skript führt für die konfigurierten Collections des Online CaaS einen PUT-Request aus. Dieser erzeugt die Aggregationen, mit deren Hilfe alle in den erweiterten Collections enthaltenen CMS Blöcke für Spryker zum Import bereitgestellt werden. Das Skript benötigt dafür die Liste der betreffenden Collections, die sich ihm mithilfe des optionalen Parameters caas_collections übergeben lässt.

Der Parameter besitzt standardmäßig den Wert contentpages;categorypages;productpages;technical und muss daher im Referenzprojekt nicht konfiguriert werden. Um den Default-Wert zu überschreiben, ist der Parameter caas_collections im Eigenschaftendialog des Skripts hinzuzufügen. Sein Wert muss einer per Semikolons separierten Liste aller Collections, für die eine Aggregation zu erzeugen ist, entsprechen.

deployparams
Abbildung 15. Konfigurationsparameter

3.7.3. Trigger Spryker Import

Die Erstellung und Bearbeitung redaktioneller Inhalte findet FirstSpirit-seitig im ContentCreator statt. Sie werden nach der Freigabe per Deployment in den Online CaaS übertragen und aus diesem von Spryker importiert, um sie in den Shop zu integrieren. Um die Inhalte Spryker-seitig stets aktuell zu halten, muss der Importprozess durch das Deployment angestoßen werden. Der Auftrag enthält daher die Skript-Aktion Trigger Spryker Import. Das Skript aktiviert einen Spryker-seitigen Import-Job, der seinerseits den Import und die Persistierung der im Online CaaS gespeicherten Inhalte anstößt.

Trigger Spryker Import
#!executable-class
com.espirit.ecom.contentconnect.spryker.module.trigger.triggerimport.TriggerImportExecutable

Bei der Verwendung des Spryker B2C Demo Shops schlägt der Import möglicherweise beim Zugriff auf den Endpunkt access-tokens mit einem Response Code 500 fehl. In diesem Fall müssen die Key-Dateien dev_only_private.key und dev_only_public.key innerhalb des Verzeichnisses data/shop/development/current/config/Zed die Berechtigung 600 bzw. 660 erhalten.

Referenzen auf Kategorien oder Produkte, die Spryker-seitig gelöscht wurden oder inaktiv sind, führen zu Fehlern und Warnungen während des Imports. In diesem Zusammenhang auftretende und im Spryker-Log erfasste Fehler, werden durch die nachfolgende Aktion in das FirstSpirit-Log übertragen.

3.7.4. Trigger Fetch Spryker Logs

Die Spryker-seitige Löschung bzw. Deaktivierung von Kategorien oder Produkten, die im FirstSpirit-Projekt referenziert sind, führt zu Fehlern und Warnungen während des Imports. Diese werden standardmäßig jedoch nur im Spryker-Log erfasst. Um die Informationen zu einer Veröffentlichung gesammelt an einer Stelle bereitzustellen, müssen die Fehler und Warnungen auch im FirstSpirit-Log erfasst sein. Der Auftrag enthält daher die Skript-Aktion Trigger Fetch Spryker Logs. Sie ermittelt alle Fehler und Warnungen zu fehlenden Kategorien und Produkten aus dem Spryker-Log und überträgt sie jeweils als Warnung in das FirstSpirit-Log. Betriebsverantwortliche Personen erhalten damit die Möglichkeit, zeitnah auf die veralteten Referenzen im FirstSpirit-Projekt zu reagieren.

Trigger Fetch Spryker Logs
#!executable-class
com.espirit.ecom.contentconnect.spryker.module.trigger.triggerfetchlogs.TriggerFetchLogsExecutable

3.7.5. Trigger Spryker Cleanup

Die Erstellung und Bearbeitung redaktioneller Inhalte findet FirstSpirit-seitig statt, bevor sie per Deployment in den Online CaaS übertragen und aus diesem von Spryker importiert werden. Um den Datenbestand in beiden Systemen stets aktuell zu halten, sind aus dem FirstSpirit-Projekt gelöschte Inhalte auch Spryker-seitig zu entfernen. Der Auftrag enthält dafür die Skript-Aktion Trigger Spryker Cleanup. Das Skript stößt einen Abgleich zwischen den Inhalten an, die im Online CaaS gespeichert sowie im Datensystem Sprykers persistiert sind. Auf diesem Weg lassen sich Spryker-seitig die veralteten Daten ermitteln und anschließend entfernen.

Trigger Spryker Cleanup
#!executable-class
com.espirit.ecom.contentconnect.spryker.module.trigger.triggercleanup.TriggerCleanupExecutable

3.7.6. Send Result Mail

Die Ausführung des Deployments der in FirstSpirit erstellten bzw. bearbeiteten Inhalte erfolgt in den meisten Fällen über den ContentCreator. Der ContentCreator informiert den Redakteur jedoch nicht darüber, ob eine Publikation erfolgreich war oder fehlgeschlagen ist. Aus diesem Grund enthält der Auftrag die Skript-Aktion Send Result Mail. Diese verschickt im Fehlerfall eine E-Mail mit allen relevanten Informationen an den Empfänger, der in den Eigenschaften des Auftrags im Feld eMail-Verteiler definiert ist. Die E-Mail enthält außerdem die Möglichkeit, diese Informationen an den Technical Support der Crownpeak Technology GmbH weiterzuleiten.

Trigger Spryker Cleanup
#! executable-class
com.espirit.ecom.contentconnect.spryker.module.schedule.ReviewScheduleResultExecutable

3.8. Generierungsauftrag - Mediengenerierung

Anders als die mit FirstSpirit erstellten Inhalte, erfolgt die Übertragung der freigegebenen Medien nicht in den CaaS, sondern in ein von der Crownpeak Technology GmbH bereitgestelltes CDN. Das Referenzprojekt besitzt dafür den Auftrag Media Deployment, der innerhalb des ServerManagers im Bereich Projekt-Eigenschaften  Auftragsverwaltung angelegt ist. Er wird von der Aktion Execute Publish Media to CDN, die in der Vollgenerierung enthalten ist, angestoßen und verfügt über die Aktionen Media Generation und Publish to CDN. Diese sind in den nachfolgenden Unterkapiteln beschriebenen.

mediadeploy actions
Abbildung 16. Aktionen der Mediengenerierung

Besteht der Wunsch, anstelle des bereitgestellten CDNs der Crownpeak Technology GmbH ein lokales CDN oder ein MAM zu verwenden, unterstützt der Technical Support bei der Konfiguration.

3.8.1. Media Generation

Für die Übertragung der Medien in das von der Crownpeak Technology GmbH bereitgestellte CDN müssen diese zunächst generiert werden. Der Auftrag enthält dafür die Generierungsaktion Media Generation. Sie entspricht einer Teilgenerierung, die sich auf den Root-Knoten der Medienverwaltung bezieht.

Um Inkonsistenzen im Live-Stand zu vermeiden, sind in den Eigenschaften der Aktion die Optionen Generierungsverzeichnis vorher leeren und Freigabestand generieren zu aktivieren. Des Weiteren ist es erforderlich, dass die an dieser Stelle für die Pfaderzeugung gewählte URL Factory und die URL-Factory für Mediennutzung, die in der Projekt-Komponente des CaaS konfiguriert ist, identisch sind.

mediageneration settings
Abbildung 17. Eigenschaften der Aktion Media Generation

3.8.2. Publish to CDN

Im Anschluss an die Generierung der Medien erfolgt ihre Übertragung in das CDN. Der Auftrag enthält dafür die Aktion Publish to CDN. Diese Aktion wird im Cloud-Umfeld durch die Cloud-Abteilung der Crownpeak Technology GmbH hinzugefügt und ist in diesem Fall bereits vorkonfiguriert. Eine weitere Konfiguration ist nicht erforderlich.

Im On-Premises-Umfeld ist eine manuelle Erzeugung und Konfiguration dieser Aktion erforderlich. Die dafür notwendigen Infomationen werden von der Crownpeak Technology GmbH bereitgestellt.

mediageneration publication
Abbildung 18. Publish to CDN

3.9. Generierungsauftrag - Vorschaugenerierung

Unter bestimmten Umständen kann es vorkommen, dass die Datenbestände aus dem FirstSpirit-Projekt, dem CaaS und in Spryker divergieren. Die Datenbestände des Online CaaS und in Spryker lassen sich in diesem Fall durch eine Vollgenerierung aktualisieren. Im Gegensatz dazu müssten für die Aktualisierung des Preview CaaS alle Seiten innerhalb des FirstSpirit-Projekts einzeln neu gespeichert werden.

Das Referenzprojekt enthält aus diesem Grund den Auftrag Spryker Preview Deployment, der innerhalb des ServerManagers im Bereich Projekt-Eigenschaften  Auftragsverwaltung angelegt und ausschließlich von Projektadministratoren ausführbar ist. Der Auftrag besitzt mit Ausnahme der Aktionen Execute Publish Media to CDN, Setup CaaS Blocks Aggregations, Trigger Fetch Spryker Logs und Send Result Mail dieselben Aktionen wie die Vollgenerierung. Im Vorschaufall werden die Informationen direkt aus dem FirstSpirit-Projekt bzw. dem Preview CaaS bezogen und es findet keine Verarbeitung in Spryker statt. Aus diesem Grund ist die Erzeugung von Aggregationen sowie die Publizierung von Medien und die Ermittlung von Spryker-Logs für die Vorschaugenerierung nicht notwendig. Da die Vorschaugenerierung außerdem aus dem ServerManager heraus gestartet wird, ist der Versand einer E-Mail an einen Adminstrator ebenfalls nicht erforderlich.

Nach dem Import eines FirstSpirit-Projekts ist die Durchführung eines Inhaltsabgleichs zwingend erforderlich. Dafür müssen jedoch sowohl die FirstSpirit- als auch die Spryker-seitigen Konfigurationsschritte vollständig durchgeführt sein.

previewdeploy actions
Abbildung 19. Aktionen der Vorschaugenerierung

Innerhalb der Aktionen Initialize CaaS Generation, CaaS Generate, Trigger Spryker Import und Trigger Spryker Cleanup sind verschiedene Einstellungen notwendig.

Initialize CaaS Generation

Die Aktion Initialize CaaS Generation setzt unter anderem die Definition eines API Keys sowie einer CaaS URL voraus. Im Fall der Vorschaugenerierung sind für beide Parameter die Daten des Preview CaaS anzugeben.

Der API Key erfordert in diesem Fall sowohl Lese- als auch Schreibrechte.

Eine Beschreibung der Aktion und der für sie erforderlichen Parameter ist in der Content as a Service-Dokumentation enthalten.

CaaS Generate

Während der Vorschaugenerierung darf diese Aktion lediglich den Current-Stand der Inhalte berücksichtigen. Aus diesem Grund muss die Checkbox Freigabestand generieren in den Eigenschaften der Aktion deaktiviert sein.

Eine Beschreibung der Aktion ist in der Content as a Service-Dokumentation enthalten.

deploy caas generate
Abbildung 20. Eigenschaften der Aktion CaaS Generate
Trigger Spryker Import

Der Import darf im Vorschaufall lediglich die Inhalte des Preview CaaS berücksichtigen. Dafür ist in den Eigenschaften der Aktion der Parameter triggerStagedContentImport hinzuzufügen und für ihn der Wert true anzugeben. Der Parameter besitzt standardmäßig den Wert false und wird aus diesem Grund nicht in der gleichnamigen Aktion der Vollgenerierung benötigt.

Im Auftrag des Referenzprojekts ist diese Einstellung bereits vorgenommen.

Trigger Spryker Cleanup

Äquivalent zum Import darf auch die Cleanup-Aktion lediglich die Inhalte des Preview CaaS berücksichtigen. Der Aktion muss daher in ihren Eigenschaften der Parameter triggerStagedContentCleanup hinzugefügt und für diesen der Wert true definiert werden. Auch dieser Parameter besitzt standardmäßig den Wert false und ist daher in der Vollgenerierung optional.

Diese Einstellung ist ebenfalls bereits im Auftrag des Referenzprojekts enthalten.

Innerhalb des FirstSpirit-Projekts gelöschte CMS Pages werden nur dann auch Spryker-seitig gelöscht, wenn sie zuvor nicht publiziert wurden. Andernfalls bleiben sie aufgrund technischer Restriktionen zunächst in Spryker erhalten und werden erst bei der Ausführung einer Vollgenerierung entfernt.

3.10. Arbeitsabläufe

Die Freigabe, die Löschung und die Publizierung von Inhalten erfolgt innerhalb des bereitgestellten Referenzprojekts über Arbeitsabläufe. Diese sind dem Projekt bereits hinzugefügt und werden in den nachfolgenden Unterkapiteln beschrieben.

3.10.1. Freigabe-Arbeitsablauf für die Navigation

Das Referenzprojekt stellt die Möglichkeit zur Verfügung, eine bestehende Navigation zu erweitern oder eine komplett neue Navigation zu erzeugen. Ebenso wie bei Inhaltsänderungen ist eine Freigabe der Änderungen notwendig, um diese in den Live-Stand zu publizieren. Das Referenzprojekt enthält daher den Arbeitsablauf Freigabe der Navigation, für dessen Ausführung das Freigabe-Recht erforderlich ist. Der Arbeitsablauf führt lediglich die Freigabe einer globalen Seite für die Navigation durch und ist aus diesem Grund ausschließlich in den Globalen Einstellungen aktiviert. Er besitzt weder eine Konfliktbehandlung noch folgt er dem Vier-Augen-Prinzip.

3.10.2. Lösch-Arbeitsablauf für automatisiertes Löschen

Das Referenzprojekt enthält den Report Lost and Found, der eine Übersicht aller verwaisten Produkt- und Kategorieseiten anzeigt. Dabei handelt es sich um Seiten, die Referenzen auf Spryker-seitig gelöschte bzw. inaktive Produkte oder Kategorien beinhalten.

Jeder Eintrag des Reports besitzt einen Lösch-Button, der eine Entfernung der entsprechenden Seite ermöglicht. Das Referenzprojekt enthält dafür den Arbeitsablauf Direktes Löschen, der durch den Button angestoßen wird. Mit Ausnahme des Vier-Augen-Prinzips entspricht seine Funktionalität dem des im nachfolgenden Kapitel beschriebenen Lösch-BasicWorkflows. Zusätzlich zur Löschung der Seite, gibt der Arbeitsablauf die übergeordnete Struktur frei und führt abschließend ein Voll-Deployment durch.

3.10.3. BasicWorkflows

Die Freigabe, die Löschung und die Publizierung von Inhalten durch Redakteure erfolgt innerhalb des bereitgestellten Referenzprojekts FirstSpirit Connect for Spryker Commerce OS Reference Project über die BasicWorkflows. Diese wurden projektspezifisch angepasst und durch die Möglichkeit erweitert, eine Vollgenerierung auszuführen. Ebenso wie die Option der direkten Freigabe bzw. des direkten Löschens steht diese Möglichkeit jeweils nur den Rollen zur Verfügung, die das Freigabe- bzw. Löschen-Recht besitzen. Im Referenzprojekt handelt es sich dabei um die Gruppe ChiefEditors.

Beide Arbeitsabläufe verschicken darüber hinaus eine E-Mail an den Benutzer, der die Freigabe bzw. Löschung durchgeführt (und nicht nur angefordert) hat. Diese E-Mail teilt im Erfolgsfall lediglich die erfolgreiche Ausführung des Arbeitsablaufs mit. Im Fehlerfall weist sie darauf hin, dass der im Deployment-Auftrag angegebene Empfänger alle erforderlichen Informationen erhalten hat und zu kontaktieren ist.

Das nachfolgende Unterkapitel erläutert die vorgenommenen Anpassungen.

Installation des BasicWorkflows-Moduls

Vor der Verwendung der Arbeitsabläufe muss zunächst das BasicWorkflows-Modul auf dem FirstSpirit-Server installiert und die Web-Komponente aktiviert sein. Die dafür notwendigen Schritte sind analog zur Installation der anderen Module und der Aktivierung der zugehörigen Web-Komponenten. Standardmäßig sind diese Schritte bereits durchgeführt.

Der Einsatz der BasicWorkflows im ContentCreator erfordert darüber hinaus die Auswahl des bereitgestellten BasicWorkflows Status Providers im Bereich Projekt-Eigenschaften  ContentCreator innerhalb des ServerManagers. Im Referenzprojekt FirstSpirit Connect for Spryker Commerce OS Reference Project ist diese Einstellung ebenfalls bereits vorgenommen.

basicwfs
Abbildung 21. Element Status Provider

Vorlagen

Die BasicWorkflows benötigen verschiedene Vorlagen. Diese müssen üblicherweise über das Kontextmenü in das verwendete FirstSpirit-Projekt importiert werden. Im Referenzprojekt sind sie jedoch bereits enthalten und ein Import der Vorlagen ist somit nicht notwendig.

Die im Referenzprojekt enthaltenen Vorlagen wurden projektspezifisch angepasst und durch weitere Vorlagen ergänzt. Besteht der Wunsch, die im Referenzprojekt enthaltenen Arbeitsabläufe in einem anderen Projekt zu verwenden, sind diese Vorlagen und nicht die des BasicWorkflows-Moduls in das andere Projekt zu übertragen.

Rechtevergabe

Im letzten Schritt müssen die Arbeitsabläufe in den einzelnen Verwaltungen erlaubt werden, um auf FirstSpirit-Elementen ausgeführt werden zu können. Dafür lässt sich auf den Root-Knoten der Verwaltungen über den Kontextmenüeintrag Extras  Rechte ändern die Rechtevergabe öffnen. Dieser Schritt ist im Referenzprojekt ebenfalls bereits durchgeführt und entfällt damit.

Die auf den Root-Knoten der Verwaltungen gesetzten Rechte zur Ausführung der Arbeitsabläufe beziehen sich auf die Gruppe Everyone. Falls dies nicht gewünscht ist, muss eine manuelle Anpassung der Rechte erfolgen.

Nähere Informationen zur Installation, Konfiguration und Funktionalität der Arbeitsabläufe finden Sie in der BasicWorkflows-Dokumentation.

3.10.4. Projektspezifische Anpassungen

Die BasicWorkflows besitzen standardmäßig zwei Möglichkeiten, ein Element freizugeben bzw. zu löschen:

  • Direkte Freigabe | Direkt Löschen

  • Anfordern

In beiden Fällen steht die direkte Option jeweils nur den Rollen zur Verfügung, die das Freigabe- bzw. das Löschen-Recht besitzen. Im Referenzprojekt handelt es sich dabei um die Gruppe ChiefEditors. Andernfalls lässt sich eine Freigabe bzw. eine Löschung lediglich anfordern und einem nächsten Bearbeiter zuweisen. Dieser lehnt die Anforderung entweder ab, indem er manuell einen Konflikt auslöst, oder er stößt die Freigabe bzw. Löschung des Elements durch die Weiterschaltung des Arbeitsablaufs an.

Beide im Referenzprojekt bereitgestellten Arbeitsabläufe wurden projektspezifisch angepasst und durch die Möglichkeit erweitert, neben der Freigabe bzw. Löschung einer Seite eine Vollgenerierung auszuführen. Dafür wurde sowohl ihrem Start-Dialog als auch dem Dialog der Prüfung ein zusätzlicher Button hinzugefügt.

Im Freigabe-Arbeitsablauf handelt es sich dabei um den Button Publikation der Seite. Er entspricht der Transition trigger_release_and_deploy, die ebenso wie die direkte Freigabe nur mit dem Freigabe-Recht ausführbar ist.
Der Lösch-Arbeitsablauf hat den Button Löschen mit VP erhalten, der die Transition trigger_delete_and_deploy repräsentiert und sowohl das Freigabe- als auch das Löschen-Recht voraussetzt.

wf dialogs
Abbildung 22. Erweiterung des Freigabe-Arbeitsablaufs

Beide Buttons führen das Skript set_value_for_deployment aus, das die Variable deploymentTriggered setzt. Diese wird im letzten Schritt des jeweiligen Arbeitsablaufs im Skript trigger_full_deployment ausgewertet und definiert, ob dieser lediglich eine Freigabe bzw. Löschung oder zusätzlich eine Vollgenerierung ausführt.

Um die Veröffentlichung anstoßen zu können, muss der durch das Skript trigger_full_deployment aufgerufenen Executable der Name der entsprechenden Vollgenerierung bekannt sein. Die Executable greift dafür auf die Combobox Veröffentlichungsauftrag zu, die im Reiter Veröffentlichung der Projekt-Komponente enthalten ist, und fragt den in ihr ausgewählten Auftrag ab. Innerhalb des Referenzprojekts ist an dieser Stelle die Vollgenerierung Spryker Deployment selektiert.

Beide Arbeitsabläufe verschicken außerdem nach ihrer Ausführung eine E-Mail an den Benutzer, der die Freigabe bzw. Löschung ausgeführt (und nicht nur angefordert) hat. Diese E-Mail teilt entweder lediglich die erfolgreiche Ausführung des Arbeitsablaufs mit oder macht auf einen während der Publikation aufgetretenen Fehler aufmerksam. In diesem Fall weist die E-Mail ebenfalls darauf hin, dass der im Deployment-Auftrag angegebene Empfänger alle benötigen Informationen erhalten hat und zu kontaktieren ist. Dies ist erforderlich, da nur Projektadministratoren Fehler im Deployment-Auftrag auflösen können.

Sowohl im Erfolgs- als auch im Fehlerfall greift die im letzen Schritt des jeweiligen Arbeitsablaufs aufgerufene Executable für den Versand der entsprechenden E-Mail auf die technische Seitenvorlage html_mail_template zu. Diese enthält die Texte aller E-Mails, die durch die Arbeitsabläufe oder Deployment-Aufträge verschickt werden.

Die Benachrichtigung des im Deployment-Auftrag angegebenen Empfängers geschieht über die Auftragsaktion Send Result Mail. Der Versand dieser E-Mail erfolgt bei allen während der Generierung auftretenden Fehlern und ist nicht an die Ausführung eines Arbeitsablaufs gekoppelt.

Da der Lösch-Arbeitsablauf lediglich für die Löschung dynamischer Inhaltsseiten sowie von Produkt- und Kategorieseiten verwendbar ist, wurde darüber hinaus seine Einblendelogik erweitert. Die neue Abfrage bewirkt die Ausblendung des Arbeitsablaufs für alle Seiten, die nicht einer Inhalts-, Produkt- oder Kategorieseite entsprechen.

Nähere Informationen zur Funktionalität der Arbeitsabläufe finden Sie in der BasicWorkflows-Dokumentation.

3.11. Projekteinstellungen

Für die Verknüpfung von FirstSpirit und Spryker sind einige projektspezifische Informationen unentbehrlich. Sie werden über das Formular der Projekteinstellungen erfasst und sind innerhalb des verwendeten Projekts anzugeben.

Innerhalb des mitgelieferten Referenzprojekts existiert die Projekteinstellungen-Seite mit der notwendigen Konfiguration bereits. In diesem Fall muss die Erzeugung der Vorlage sowie der erforderlichen Komponenten somit nicht mehr erfolgen. Auch die Definition der Einstellungsseite in den Optionen des Projekts im ServerManager ist nicht mehr erforderlich.

Das Formular der Projekteinstellungen im Referenzprojekt gliedert sich in die Tabs Allgemein und Static Pages, in denen unterschiedliche Informationen anzugeben sind:

Aktiver Store

An dieser Stelle ist der Store auszuwählen, in den die erstellten Inhalte publiziert werden sollen. Die Auswahl wird an unterschiedlichen Stellen innerhalb der FirstSpirit-Vorlagen ausgelesen.

Seitenreferenz

Das mit diesem Feld verknüpfte Feature steht in der aktuellen Version noch nicht zur Verfügung. Es besitzt daher zu diesem Zeitpunkt noch keine Funktion.

psettings general
Abbildung 23. Projekteinstellungen - Allgemein
Static Page URLs

Diese Eingabekomponente stellt die Möglichkeit bereit, statischen Seiten eine relative URL zuzuweisen. Dies ist notwendig, da statische Seiten standardmäßig keine URL besitzen und Inhaltsseitenverweise auf sie somit nicht möglich wären.

Die Definition der URLs erfordert zunächst eine Ermittlung aller statischen Seiten. Innerhalb des Referenzprojekts wird dafür mithilfe des Buttons Statische Seiten Templates Import der Inhalt des Vorlagenordners static_pages ausgelesen, der alle Seitenvorlagen für statischen Seiten enthält. Pro Vorlage wird automatisch ein Eintrag erzeugt, der eine Referenz auf die Vorlage und ein sprachabhängiges Feld für die zu definierende relative URL enthält.

psettings staticpages
Abbildung 24. Projekteinstellungen - Static Pages

Eine spätere Änderung der definierten URLs erfordert sowohl die Ausführung der Vollgenerierung als auch der Vorschaugenerierung.

4. Referenzprojekt

Das FirstSpirit Connect for Spryker Commerce OS-Modul stellt unterschiedliche Möglichkeiten bereit, auf Shop-Inhalte aus Spryker zuzugreifen und diese in FirstSpirit zu verwenden. Dafür werden sowohl innerhalb des FirstSpirit-Projekts als auch Spryker-seitig verschiedene Vorlagen benötigt. Diese und die zwischen ihnen bestehenden Beziehungen werden in den nachfolgenden Unterkapiteln anhand des mitgelieferten Referenzprojekts beschrieben.

Die im Referenzprojekt enthaltenen Absatz- und Seitenvorlagen benötigen für ihre Verwendung Spryker-seitig verschiedene Twig-Templates. Die Beschreibungen in den nachfolgenden Unterkapiteln setzen die Existenz dieser Templates voraus.

4.1. Erweiterung bestehender statischer Seiten

Das FirstSpirit Connect for Spryker Commerce OS-Modul bietet Redakteuren die Möglichkeit, statische Seiten, die Spryker-seitig bereits existieren, mit FirstSpirit-Inhalten anzureichern. Die Seiten werden dafür mithilfe des Omnichannel Managers innerhalb des ContentCreators dargestellt und integrieren sich so nahtlos in den mit FirstSpirit bekannten Redaktionsprozess.

Die Erweiterung statischer Seiten in FirstSpirit setzt neben der Einbindung des Omnichannel Managers, die ein Schritt der Installation ist, die Befüllung des Ausgabekanals der Seiten- und Absatzvorlagen voraus. Darüber hinaus ist eine Spryker-seitige Anpassung der entsprechenden Twig-Templates notwendig.

4.1.1. Seitenvorlage

Die Bearbeitung redaktioneller Inhalte erfolgt im FirstSpirit-Projekt grundsätzlich auf Basis einer Seitenreferenz. Sie und die ihr zugrundeliegende Seite müssen zunächst im FirstSpirit-Projekt angelegt werden. Innerhalb des Referenzprojekts FirstSpirit Connect for Spryker Commerce OS Reference Project läuft die Erzeugung der Seitenreferenz und ihrer Seite automatisch im Hintergrund und für den Redakteur unsichtbar ab. Das Skript infer_page_storage_information ermittelt dabei anhand der im IndexController definierten Page Id die zugehörige FirstSpirit-Seitenvorlage.

Die im Referenzprojekt enthaltene Seitenvorlage homepage stellt ein Beispiel für eine statische Seite dar. Der folgende Code-Ausschnitt zeigt den Ausgabekanal dieser Seitenvorlage:

Ausgabekanal der Seitenvorlage homepage
$CMS_TRIM(level:1)$
   $CMS_SET(json, {:})$
   $CMS_SET(previewId, previewId(element:#global.node))$
   $CMS_SET(void, json.put("previewId", "" + previewId))$
   $CMS_SET(void, json.put("pagetype", "static"))$
   $CMS_SET(void, json.put("identifier", #global.node.uid))$

   $CMS_SET(blocks, [])$
   $CMS_FOR(bodyName, #global.page.template.bodies.map(body -> body.name))$
      $CMS_VALUE(#global.page.body(bodyName))$
   $CMS_END_FOR$

   $CMS_SET(void, json.put("blocks", blocks))$

   $CMS_VALUE(json.toJSON)$
$CMS_END_TRIM$

Die Seitenvorlage bildet das Twig-Template home.twig ab und besitzt die Inhaltsbereiche fs_slt_2 und fs_slt_3. Die Inhaltsbereiche ermöglichen die Ergänzung redaktioneller Inhalte, wofür im Referenzprojekt verschiedene Absatzvorlagen zur Verfügung stehen. Ihr Inhalt wird dem in der Vorlage erzeugten JSON-Objekt json hinzugefügt.

Zusätzlich zu den redaktionellen Inhalten werden dem JSON-Objekt die previewId, der identifier und der pagetype übergeben: Die previewId dient der Identifikation der Seitenreferenz und ermöglicht deren Dekoration im ContentCreator sowie ihr Mapping auf das Spryker-seitige Twig-Template. Die Identifikation der Seitenreferenz für die Vorschau erfolgt über das JavaScript des Omnichannel Managers. Die Spryker-seitige Erzeugung der Seite geschieht mithilfe des Identifiers. Er gewährleistet, dass die Seite in Spryker eindeutig ermittelbar ist. Außerdem muss bekannt sein, ob die zugrundeliegende Seite statisch oder dynamisch ist. Diese Information zeigt der Page Type an.

Das erzeugte JSON-Objekt ist ein Teil des zu generierenden CaaS-Items, dessen Spryker-seitige Persistierung durch den Importer erfolgt.

4.1.2. Absatzvorlage

Die im Referenzprojekt enthaltene Seitenvorlage homepage stellt ein Beispiel für eine statische Seite dar. Sie enthält die Inhaltsbereiche fs_slt_2 und fs_slt_3. Diese ermöglichen die Ergänzung redaktioneller Inhalte. Dafür stehen unterschiedliche Absatzvorlagen zur Verfügung, die alle auf demselben Prinzip basieren. Eine von ihnen ist die Absatzvorlage shoppable_video, die an dieser Stelle exemplarisch beschrieben ist.

Innerhalb des Ausgabekanals des Shoppable Video-Absatzes erfolgt zunächst die Definition diverser allgemeiner Informationen und ihre Speicherung im Array block: Die previewId dient der Identifikation des Absatzes und ermöglicht dessen Bearbeitung im ContentCreator. Die Felder active und store_names geben an, dass der durch den Absatz repräsentierte CMS Block Spryker-seitig aktiv und in dem in den Projekteinstellungen ausgewählten Store sichtbar ist.

Die Ausgabe aller Absätze erfolgt Spryker-seitig durch das Twig-Template fs_molecule_block. Dieses entspricht einem generischen Template, das die Ausgabe aller Moleküle steuert. Um die Ausgabe eines Absatzes sowohl im Vorschaufall als auch im Live-Stand zu gewährleisten, müssen der Name und der Pfad dieses generischen Twig-Templates im CaaS-Item gespeichert sein. Beide Angaben sind daher in den allgemeinen Informationen des Absatzes enthalten.

Definition allgemeiner Informationen im Ausgabekanal des Absatzes
$CMS_SET(block,{:})$

$-- Defining general block data --$
$CMS_SET(void, block.put("previewId", "" + previewId()))$
$CMS_SET(void, block.put("active", "1"))$
$CMS_SET(void, block.put("store_names", [ps_activeStore]))$
$CMS_SET(void, block.put("template_name", "fs_molecule_block"))$
$CMS_SET(void, block.put("template_path", "@CmsBlock/template/fs_molecule_block.twig"))$

Die Formatvorlage block_name_render ermittelt anschließend den Blocknamen. Dieser setzt sich aus dem Namen des übergeordneten Inhaltsbereichs sowie der ID des Absatzes zusammen.

Die Formatvorlage block_key_render verhält sich analog zur Formatvorlage block_name_render. Im Gegensatz zu dieser ermittelt sie jedoch nicht den Blocknamen, sondern den eindeutigen Key des entsprechenden Blocks.

Mithilfe der Formatvorlage additional_block_attributes_render werden dem Block weitere Attribute hinzugefügt. Bei diesen Attributen handelt es sich um den Slot-Key und die Position des Blocks innerhalb des Slots sowie um den Page Type und eine eindeutige ID.

Der Importer setzt das Feld placeholders im generierten CaaS-Item voraus. Daher ist es an dieser Stelle anzulegen, obwohl es keine Daten besitzt.

Ermittlung spezifischer Informationen im Ausgabekanal des Absatzes
$CMS_SET(set_pageType, json.get("pagetype"))$

$-- Add block name attribute to block object (page type dependent) --$
$CMS_RENDER(template: "block_name_render", rt_pageType: set_pageType, rt_blockObject: block)$

$-- Add block key attribute to block object (page type dependent) --$
$CMS_RENDER(template: "block_key_render", rt_pageType: set_pageType, rt_blockObject: block)$

$-- Add additional block attributes to block object (page type dependent) --$
$CMS_RENDER(template: "additional_block_attributes_render", rt_pageType: set_pageType, rt_blockObject: block)$

$-- Defining placeholder data of the block --$
$CMS_SET(placeholders,{:})$
$CMS_SET(void, block.put("placeholder",placeholders))$

Das Array data beinhaltet die im Formular des Absatzes gepflegten redaktionellen Inhalte. Diese entsprechen der Video Id des ausgewählten YouTube-Videos und einer Liste von Video-Items, die auf der nachfolgend beschriebenen Absatzvorlage shoppable_video_item basieren. Sie werden zu definierten Zeitpunkten des Videos angezeigt. Für die Anzeige des Videos benötigt der Player die an dieser Stelle angegebene previewId. Der Absatz wird Spryker-seitig durch das Molekül fs-shoppable-video repräsentiert, dessen Name ebenfalls im data-Array enthalten ist.

Der Importer erwartet die Informationen im Kontext der aktuellen Sprache. Aus diesem Grund erfolgt eine Ermittlung des entsprechenden Sprachkürzels, dem das Array data zugeordnet wird.

Im Vorschaufall werden die Inhalte des Absatzes anschließend direkt ausgegeben. Andernfalls fügt der letzte Schritt den Absatz dem in der Seitenvorlage definierten Array blocks hinzu, das alle Absätze einer Seite enthält und sie in das zu generierende CaaS-Item integriert.

Verarbeitung der redaktionellen Inhalte im Ausgabekanal des Absatzes
$CMS_SET(data,{:})$
$CMS_SET(void, data.put("moleculename", "fs-shoppable-video"))$
$CMS_SET(void, data.put("videoId", if(!st_video.empty,st_video.values.first.id)))$
$CMS_SET(void, data.put("previewId", previewId()))$

$CMS_SET(items,[])$
$CMS_VALUE(st_items)$
$CMS_SET(void, data.put("items", items))$

$CMS_SET(locale, #global.language.getLocale())$
$CMS_SET(localeAbbr, locale.getLanguage() + "_" + locale.getCountry())$
$CMS_SET(localizedData,{:})$
$CMS_SET(void, localizedData.put(localeAbbr, data))$
$CMS_SET(void, block.put("data", localizedData))$

$CMS_IF(#global.is("WEBEDIT") && !isSet(caas_preview_generation))$
   $CMS_VALUE(block.toJSON)$
$CMS_ELSE$
   $CMS_SET(void, blocks.add(block))$
$CMS_END_IF$

Wie zuvor erwähnt basieren die einzelnen Video-Items auf der Absatzvorlage shoppable_video_item. Innerhalb des Ausgabekanals dieser Vorlage erfolgt die Erfassung der redaktionellen Inhalte für ein einzelnes Video-Item und ihre Speicherung im Array item. Die redaktionellen Inhalte entsprechen dem Zeitpunkt, zu dem das Video-Item angezeigt wird, einem Bild, einem Text und einem Verweis auf die Detailseite eines auszuwählenden Produkts. Der letzte Schritt fügt das einzelne Video-Item dem in der Absatzvorlage shoppable_video definierten Array items hinzu, das alle Video-Items enthält und sie in das zu generierende CaaS-Item integriert.

Ausgabekanal des Video-Items
$CMS_SET(item, {"time": st_time})$

$CMS_IF(!st_picture.empty)$
   $CMS_SET(void, item.put("picture", {
      "imageUrl": ref(st_picture, res:"CONTENT_IMAGE", abs:1).url,
      "ambilight": !st_ambilight.empty && st_ambilight
   }))$
   $CMS_IF(!#global.release)$
      $CMS_SET(void, item.picture.put("previewId", previewId(element: st_picture)))$
   $CMS_END_IF$
$CMS_END_IF$

$CMS_IF(!st_text.empty)$
   $CMS_SET(void, item.put("text", st_text.normalize.toText(true)))$
$CMS_END_IF$

$CMS_IF(!st_product.empty)$
   $CMS_SET(void, item.put("productId", st_product.identifiers.get(0)))$
$CMS_END_IF$

$CMS_SET(void, items.add(item))$

Für die Eingabe des Anzeigezeitpunkts, des Bilds, des Textes sowie des Verweises eines Video-Items besitzt der Bearbeitungsdialog im ContentCreator den Button Open Video. Dieser öffnet einen weiteren Dialog, in dem das ausgewählte Video sichtbar und abspielbar ist. Mithilfe einer Zeitleiste lassen sich die Video-Items innerhalb dieses Dialogs intuitiv erstellen, bearbeiten oder löschen.

videoitem
Abbildung 25. Bearbeitungsdialog für Video-Items

4.1.3. Twig-Templates

Die Erstellung und Bearbeitung redaktioneller Inhalte erfolgt FirstSpirit-seitig im ContentCreator. In diesem ist mithilfe des Omnichannel Managers die Storefront eingebettet. Diese greift ihrerseits auf den Preview CaaS zu und ermittelt aus diesem die aktuellen FirstSpirit-Inhalte. Per FirstSpirit-Deployment werden diese Inhalte in den Online CaaS übertragen. Dieser stellt sie dem Importer zur Verfügung, der sie nach Spryker überträgt und dort persistiert.

Das Twig-Template home.twig stellt Spryker-seitig eine statische Seite dar und ist unter dem Pfad src/Pyz/Yves/HomePage/Theme/default/views/home zu finden. Um diese Seite im ContentCreator bearbeitbar zu machen, ist eine Ersetzung der in ihr enthaltenen CMS Slots notwendig.

Die Slots repräsentieren die Inhaltsbereiche der jeweiligen FirstSpirit-Seitenvorlage. Aus diesem Grund müssen der Key des CMS Slots sowie der Name des entsprechenden Inhaltsbereichs übereinstimmen und jeweils mit dem Präfix fs-slt beziehungsweise fs_slt beginnen. Dabei ist zu beachten, dass Bindestriche im Key des Slots innerhalb von FirstSpirit durch Unterstriche ersetzt werden. Der Slot fs-slt-2 entspricht somit dem Inhaltsbereich fs_slt_2.

Die Einbindung eines Slots erfolgt über den Spryker-Standardbefehl cms_slot, der seinerseits das FirstSpiritPreviewSlotBlockWidgetCmsSlotContentPlugin aufruft. Dieses ist ein Bestandteil der Auslieferung und erfordert eine Erweiterung des ShopCmsSlotDependencyProviders. Es berücksichtigt im Gegensatz zu dem in Spryker enthaltenen CmsSlotBlockWidget ausschließlich die im CaaS gespeicherten Daten.

Das Twig-Template home.twig wird im Referenzprojekt durch die Seitenvorlage homepage abgebildet. Sie stellt ein Beispiel für eine statische Seite dar und besitzt die Inhaltsbereiche fs_slt_2 und fs_slt_3. Das folgende Code-Beispiel zeigt die Einbindung der gleichnamigen Slots innerhalb des Twig-Templates, um die statische Seite im ContentCreator bearbeitbar zu machen.

Innerhalb des Twig-Templates ist die ID idCmsPage zu definieren und jedem Block zu übergeben. Sie setzt sich aus dem Page Type sowie dem Namen der FirstSpirit-Seite zusammen.

Erweiterung des Twig-Templates home.twig
{% extends template('page-layout-main') %}

{% define data = {
   idCmsPage: 'static_homepage',
} %}

{% block pageInfo %}{% endblock %}

{% block container %}
   {% cms_slot 'fs-slt-2' with{
      idCmsPage: 'static_homepage',
   }%}

   <div class="container container--home-page">
      <main>
         {% block content %}
            {% cms_slot 'fs-slt-3' with{
               idCmsPage: 'static_homepage',
            }%}
         {% endblock %}
      </main>
   </div>
{% endblock %}

Die in der Seitenvorlage homepage enthaltenen Inhaltsbereiche fs_slt_2 und fs_slt_3 ermöglichen die Ergänzung redaktioneller Inhalte. Dafür stehen innerhalb des Referenzprojekts verschiedene Absatzvorlagen zur Verfügung, für die Spryker-seitig ein zugehöriges Block Twig-Template existieren muss. Eine dieser Vorlagen ist die Absatzvorlage shoppable_video, die Spryker-seitig durch das Molekül fs-shoppable-video repräsentiert wird. Dieses ist ein Bestandteil des in der Auslieferung enthaltenen Spryker- Moduls firstspirit-reference-components und Spryker-seitig im Verzeichnis FirstSpiritReferenceComponents abgelegt.

Der folgende Code-Ausschnitt zeigt den Inhalt des Moleküls fs-shoppable-video in stark gekürzter Form:

Molekül fs-shoppable-video
{% extends model('component') %}

{% define config = {
   name: 'fs-shoppable-video',
   tag: 'fs-shoppable-video'
} %}

{% define data = {
   fsBlockData: [],
} %}

{% block body %}
   [...]
   <fs-youtube-player video-id="{{ data.fsBlockData.videoId }}" nocookie muted>
      {% for item in data.fsBlockData.items %}
         <div data-time="{{ item.time }}">
            {% set url = item.productId is defined ? getProductPageUrl(item.productId):null %}
            <a href="{{url}}">
               {% set ambilight = item.picture.ambilight is defined and item.picture.ambilight %}
               <span class="picture{{ambilight ? 'with-ambilight':''}}"
                  style="background-image: url('{{ item.picture.imageUrl }}');">
               </span>
               [...]
               {{ item.text | raw }}
               [...]
            </a>
            [...]
         </div>
      {% endfor %}
   </fs-youtube-player>
   <script type="module" src="https://www.unpkg.com/fs-youtube-player"></script>
{% endblock %}

Innerhalb des Templates werden zunächst der Name und das Tag des Moleküls definiert. Anschließend erfolgt die Erzeugung des fsBlockData-Objekts. Es ermöglicht den Zugriff auf die strukturierten Daten, die im Ausgabekanal der FirstSpirit-Absatzvorlage definiert sind. Im Vorschaufall erfolgt der Bezug dieser Daten direkt aus dem Preview CaaS. Im Gegensatz dazu stammen die Daten für den Live-Stand aus Spryker. Dafür werden sie während der FirstSpirit-Generierung aus dem Online CaaS importiert und Spryker-seitig persistiert. Das fsBlockData-Objekt und das FirstSpirit-seitig erstellte JSON-Objekt besitzen somit in beiden Fällen dieselbe Struktur.

Der Block body beschreibt die Ausgabe der redaktionellen Inhalte. Diese entsprechen dem Zeitpunkt, zu dem das Video-Item angezeigt wird, einem Bild, einem Text und einem Verweis auf die Detailseite eines auszuwählenden Produkts.

Die folgende Abbildung zeigt die Darstellung des CMS Blocks.

section
Abbildung 26. Darstellung des Absatzes

4.2. Erweiterung bestehender Kategorieseiten

Ebenso wie die zuvor beschriebenen statischen Seiten lassen sich auch Kategorieseiten, die Spryker-seitig bereits existieren, mithilfe des Omnichannel Managers im ContentCreator darstellen und mit redaktionellen Inhalten anreichern. Dafür ist ebenfalls die Befüllung der Ausgabekanals der Seiten- und Absatzvorlage innerhalb des FirstSpirit-Projekts sowie eine Spryker-seitige Anpassung der entsprechenden Twig-Templates notwendig.

Bestehen innerhalb des FirstSpirit-Projekts noch Referenzen auf Kategorien oder Produkte, die Spryker-seitig gelöscht wurden oder inaktiv sind, entstehen sogenannte verwaiste Seiten. Diese lassen sich über den Report Lost and Found aus dem Projekt entfernen.

4.2.1. Seitenvorlage

Genauso wie die Bearbeitung statischer Seiten erfolgt auch die Erweiterung einer Kategorieseite im FirstSpirit-Projekt auf Basis einer Seitenreferenz. Sie und die ihr zugehörige Seite werden ebenfalls automatisch im Hintergrund und für den Redakteur unsichtbar angelegt.

Das Referenzprojekt enthält die Seitenvorlage categorypage, die ein Beispiel für eine Kategorieseite darstellt und das Twig-Template catalog-with-cms-slot.twig abbildet. Der folgende Code-Ausschnitt zeigt den Ausgabekanal dieser Seitenvorlage:

Ausgabekanal der Seitenvorlage categorypage
$CMS_TRIM(level:1)$
   $CMS_SET(json, {:})$
   $CMS_SET(previewId, previewId(element:#global.node))$
   $CMS_SET(void, json.put("previewId", "" + previewId))$
   $CMS_SET(void, json.put("pageRevisionId", #global.page.revision.id))$
   $CMS_SET(void, json.put("pagetype", "category"))$
   $CMS_SET(blocks, [])$

   $CMS_VALUE(#global.page.body("banner"))$
   $CMS_VALUE(#global.page.body("top"))$
   $CMS_VALUE(#global.page.body("bottom"))$
   $CMS_SET(void, json.put("blocks", blocks))$

   $CMS_VALUE(json.toJSON)$
$CMS_END_TRIM$

Der Ausgabekanal der Kategorieseite ist nahezu identisch mit dem der Homepage, die einer statischen Seite entspricht. Er unterscheidet sich lediglich in der Angabe des Page Type, der Revision Id sowie in der Anzahl der Inhaltsbereiche. Der Page Type dient der Ermittlung des Blocknamens und muss an dieser Stelle den Wert category besitzen. Die Ermittlung des Blocknamens in Abhängigkeit des Seitentyps erfolgt durch die Formatvorlage block_name_render, die im Ausgabekanal des jeweils eingebundenen Absatzes referenziert ist. Die Inhaltsbereiche der Seitenvorlage entsprechen den Spryker-seitig definierten CMS Block-Positionen. Sie müssen daher identisch benannt sein.

4.2.2. Absatzvorlage

Zusätzlich zu dem bereits beschriebenen Shoppable Video-Absatz und dem Text-Bild-Absatz steht für die Ergänzung redaktioneller Inhalte auf Kategorieseiten die Absatzvorlage carousel_section zur Verfügung. Diese bindet wiederum ein oder mehrere Banner ein.

Das Banner ermöglicht die Auswahl eines zuschneidbaren Bilds sowie die Angabe eines Verweises, einer Überschrift und eines Untertitels. Sowohl für die Überschrift als auch für den Untertitel ist eine Textfarbe selektierbar. Im Gegensatz zu den anderen Absätzen, die sich lediglich auf Seiten für Unterkategorien verwenden lassen, ist die Einbindung des Banners auf allen Kategorieseiten möglich.

Das Banner entspricht dem Spryker-seitigen Molekül fs-banner.twig, dessen Ausgabe ebenfalls das generische Twig-Template fs_molecule_block.twig steuert. Dieses entspricht einem generischen Template, das die Ausgabe aller Moleküle reguliert.

Der Ausgabekanal des Banners ist nahezu identisch mit dem des Shoppable Video-Absatzes und unterscheidet sich lediglich in der Auswertung der zur Verfügung stehenden Eingabekomponenten. Aus diesem Grund sind keine zusätzlichen Erweiterungen erforderlich, die über die anhand des Shoppable Video-Absatzes bereits beschriebenen Anforderungen hinausgehen.

4.2.3. Twig-Templates

Die im Referenzprojekt enthaltene FirstSpirit-Seitenvorlage categorypage stellt ein Beispiel für eine Kategorieseite dar. Sie besitzt die Inhaltsbereiche banner, top und bottom und bildet das Twig-Template catalog-with-cms-slot.twig ab. Dieses ist Spryker-seitig unter dem Pfad src/Pyz/Yves/CatalogPage/Theme/default/views/catalog-with-cms-slot gespeichert und erweitert das übergeordnete Template page-layout-catalog.twig, in dem das Basis-Layout aller Kategorieseiten definiert ist.

Um Kategorieseiten im ContentCreator bearbeitbar zu machen, muss die Einbindung der CMS Blöcke innerhalb der beiden Templates über die Twig-Funktion fsSpyCmsBlock erfolgen.

Im Gegensatz zum CMS Block banner, dessen Einbindung auf allen Kategorieseiten möglich ist, sind die CMS Blöcke top und bottom lediglich auf Unterkategorieseiten verwendbar. Sollen sie ebenfalls auf allen Kategorieseiten verfügbar sein, ist für sie in Spryker das Template Catalog + CMS Slot auszuwählen.

Das folgende Code-Beispiel zeigt das Twig-Template catalog-with-cms-slot.twig inklusive der für die FirstSpirit-seitige Bearbeitung notwendigen Anpassungen. Da nur für die Positionen top und bottom Inhaltsbereiche in der FirstSpirit-Seitenvorlage existieren, erfolgt die Einbindung der CMS Blöcke ausschließlich in diesen beiden Fällen über die Twig-Funktion fsSpyCmsBlock.

Anpassung des Twig-Templates catalog-with-cms-slot.twig
{% extends template('page-layout-catalog', 'CatalogPage') %}

[...]

{% block catalogContent %}
   {% if data.categoryId %}
      <div class="catalog-cms-block catalog-cms-block--top">
         {{ fsSpyCmsBlock({category: data.categoryId, position: 'top'}) }}
         {% cms_slot 'slt-4' required ['idCategory'] with {
            idCategory: data.categoryId,
         } %}
      </div>
   {% endif %}

   {{ parent() }}

   {% if data.categoryId %}
      <div class="catalog-cms-block catalog-cms-block--bottom">
         {{ fsSpyCmsBlock({category: data.categoryId, position: 'bottom'}) }}
         {% cms_slot 'slt-6' required ['idCategory'] with {
            idCategory: data.categoryId,
         } %}
      </div>
   {% endif %}
{% endblock %}

Jeder CMS Block entspricht einem FirstSpirit-Absatz, der an einer bestimmten Position in einer Kategorieseite platziert ist. Die Verwendung von Positionen in Kategorieseiten ermöglicht Spryker-seitig das Feature CMS Block Category Connector, das innerhalb des Demo-Shops bereits konfiguriert ist. Das Feature stellt standardmäßig die Positionen top, middle und bottom bereit. Die Positionen werden FirstSpirit-seitig durch die Inhaltsbereiche der entsprechenden Seitenvorlage repräsentiert. Aus diesem Grund müssen die Namen der Inhaltsbereiche und die Namen der für Kategorieseiten definierten Positionen identisch sein.

Für die Einbindung des Banners muss das Feature zusätzlich um die Position banner erweitert werden. Dafür ist die Datei cms_block_category_position.csv innerhalb des Verzeichnisses data/import entsprechend anzupassen.

Damit die Positionen der Blöcke für Kategorieseiten bekannt sind, müssen die YAML-Dateien in data/import/local/ angepasst werden.

Erweiterung der full_EU.yaml
[...]
  - data_entity: cms-block
    source: data/import/common/common/cms_block.csv
  - data_entity: cms-block-category-position
    source: data/import/common/common/cms_block_category_position.csv
  - data_entity: cms-page
    source: data/import/common/common/cms_page.csv
[...]
Erweiterung der full_US.yaml
[...]
  - data_entity: cms-block
    source: data/import/common/common/cms_block.csv
  - data_entity: cms-block-category-position
    source: data/import/common/common/cms_block_category_position.csv
  - data_entity: cms-page
    source: data/import/common/common/cms_page.csv
[...]

Die Übernahme der neuen Position erfolgt anschließend über den nachfolgenden Befehl, der im Spryker-Projektverzeichnis auszuführen ist.

Aktualisierungsbefehl
console data:import cms-block-category-position

Eine genauere Beschreibung zur Konfiguration von Positionen für Kategorieseiten ist im Kapitel Usage for Demoshop der Spryker-Dokumentation enthalten.

Darüber hinaus ist der CMS Block banner dem übergeordneten Twig-Template page-layout-catalog.twig hinzuzufügen, das im Verzeichnis src/Pyz/Yves/CatalogPage/Theme/default/templates/page-layout-catalog abgelegt ist. Dafür muss der bereits bestehende Abschnitt block title innerhalb des Templates durch den folgenden Code ersetzt werden.

Einbindung des Banners
{% block title %}
   {% if data.category %}
      {{ fsSpyCmsBlock({category:data.category.id_category, position: 'banner'}) }}
   {% endif %}
   [...]
{% endblock %}

Das Banner entspricht Spryker-seitig dem Molekül fs-banner. Der folgende Code-Ausschnitt zeigt den Inhalt des Moleküls in stark gekürzter Form:

Molekül fs-banner
{% extends model('component') %}

{% define config = {
   name: 'fs-banner',
   tag: 'fs-banner'
} %}

{% define data = {
   fsBlockData: []
} %}

{% block body %}
   {% set url -%}
      {%- if data.fsBlockData.link is defined and data.fsBlockData.link is not empty -%}
         {%- include template('link', 'FirstSpiritPreview') with { link: data.fsBlockData.link } -%}
      {%- endif -%}
   {%- endset %}
   <figure class="fs-banner"
      {% if data.fsBlockData.variantEditorName is defined %}
         data-variant-editor-name="{{ data.fsBlockData.variantEditorName }}"
      {% endif %}
      {% if data.fsBlockData.variant is defined and data.fsBlockData.variant is not empty %}
         data-variant="{{data.fsBlockData.variant}}"
      {% endif %}
      {% if data.fsBlockData.previewId is defined and data.fsBlockData.previewId is not empty %}
         data-preview-id="{{data.fsBlockData.previewId}}"
      {% endif %}>

      [...]

      <img src="{{ data.fsBlockData.picture.imageUrl }}"
         {% if data.fsBlockData.picture.previewId is defined %}
            data-preview-id="{{ data.fsBlockData.picture.previewId }}"
            data-tpp-context-image-resolution="BANNER_IMAGE"
         {% endif %}>

      [...]

   </figure>
{% endblock %}

Innerhalb des Templates werden zunächst der Name und das Tag des Moleküls definiert. Anschließend erfolgt die Erzeugung des fsBlockData-Objekts. Es ermöglicht den Zugriff auf die strukturierten Daten, die im Ausgabekanal der FirstSpirit-Absatzvorlage definiert sind. Im Vorschaufall erfolgt der Bezug dieser Daten direkt aus dem Preview CaaS. Im Gegensatz dazu stammen die Daten für den Live-Stand aus Spryker. Dafür werden sie während der FirstSpirit-Generierung aus dem Online CaaS importiert und Spryker-seitig persistiert. Das fsBlockData-Objekt und das FirstSpirit-seitig erstellte JSON-Objekt besitzen somit in beiden Fällen dieselbe Struktur.

Der Block body beschreibt die Ausgabe der redaktionellen Inhalte. Diese entsprechen einem zuschneidbaren Bild und einem Verweis sowie einer Überschrift und einem Untertitel, für die jeweils eine Textfarbe definiert ist.

Die folgende Abbildung zeigt die Darstellung eines Karussells mit einem eingebundenen Banner im ContentCreator.

banner
Abbildung 27. Karussell mit einem Element

Die Ausgabe aller Moleküle steuert das generische Twig-Template fs_molecule_block.twig. Der folgende Code-Ausschnitt zeigt den Inhalt dieses Templates:

generisches Twig-Template für die Ausgabe aller Moleküle
{% define data = {
   fsBlockData: fsBlockData()
} %}

{% block content %}
   {% include molecule( data.fsBlockData.moleculename, 'FirstSpiritReferenceComponents') with{
      data: {
         fsBlockData: data.fsBlockData
      }
      attributes: {
         'data-attributes': data.fsBlockData.attributes | default('') | json_encode
      }
   }only %}
{% endblock %}

Wie im Twig-Template des Moleküls erfolgt in dem generischen Template zunächst die Erzeugung des fsBlockData-Objekts. Anschließend bindet der Block content das Molekül ein, das in der FirstSpirit-Absatzvorlage für den Parameter moleculename angegeben ist. Das Molekül ist Spryker-seitig im Verzeichnis FirstSpiritReferenceComponents abgelegt. Auf diesem Weg steuert das Twig-Template generisch die Ausgabe aller Moleküle und stellt das Mapping zwischen der FirstSpirit-Absatzvorlage und dem jeweiligen Spryker-seitigen Block Twig-Template her.

Das Attribut attributes ermöglicht die Bereitstellung zusätzlicher Konfigurationsattribute, die sich im Ausgabekanal einer Absatzvorlage definieren lassen. Sie werden auf diesem Weg direkt im Tag des zugehörigen Moleküls bereitgestellt, so dass auf sie mühelos per TypeScript zugegriffen werden kann. Sind innerhalb des Ausgabekanals eines Absatzes keine Konfigurationsattribute definiert, bleibt das Attribut attributes leer.

4.3. Erweiterung bestehender Produktseiten

Die Spryker-seitig bereits existierenden Produktseiten sind äquivalent zu den zuvor beschriebenen Kategorieseiten. Sie lassen sich ebenfalls mithilfe des Omnichannel Managers im ContentCreator darstellen und in diesem bearbeiten. Dies erfordert auch in diesem Fall eine Befüllung des Ausgabekanals der FirstSpirit-Seitenvorlage und eine Anpassung des zugehörigen Twig-Templates in Spryker.

Bestehen innerhalb des FirstSpirit-Projekts noch Referenzen auf Kategorien oder Produkte, die Spryker-seitig gelöscht wurden oder inaktiv sind, entstehen sogenannte verwaiste Seiten. Diese lassen sich über den Report Lost and Found aus dem Projekt entfernen.

4.3.1. Seitenvorlage

Die Bearbeitung einer Produktseite ist äquivalent zur Erweiterung einer Kategorieseite und erfolgt im FirstSpirit-Projekt ebenfalls auf Basis einer Seitenreferenz. Diese und die ihr zugehörige Seite werden automatisch im Hintergrund und für den Redakteur unsichtbar angelegt.

Die mit dem Referenzprojekt bereitgestellte Seitenvorlage productpage entspricht einer Produktseite. Sie bildet das Twig-Template pdp.twig ab und besitzt den im folgenden Code-Ausschnitt dargestellten Ausgabekanal.

Ausgabekanal der Seitenvorlage productpage
$CMS_TRIM(level:1)$
   $CMS_SET(json, {:})$
   $CMS_SET(previewId, previewId(element:#global.node))$
	$CMS_SET(void, json.put("previewId", "" + previewId))$
	$CMS_SET(void, json.put("pageRevisionId", #global.page.revision.id))$
	$CMS_SET(void, json.put("pagetype", "product"))$
	$-- Page uid is needed for later identification when setting the SKU of the page --$
	$CMS_SET(void, json.put("page_uid", #global.page.uid))$
	$CMS_SET(void, json.put("product_sku", pt_productSku))$
	$CMS_SET(blocks, [])$

	$CMS_VALUE(#global.page.body("content"))$
	$CMS_SET(void, json.put("blocks", blocks))$

	$CMS_VALUE(json.toJSON)$
$CMS_END_TRIM$

Der Ausgabekanal der Produkt- und der Kategorieseite sind nahezu identisch. Sie unterscheiden sich lediglich in der Angabe der Page UID und der Product SKU sowie in der Anzahl der Inhaltsbereiche. Die Product SKU entspricht einer eindeutigen Produkt-ID, die zusammen mit der Page UID der eindeutigen Identifizierung der Produktseite in Spryker dient. Sie wird bei der Erstellung einer Produktseite im FirstSpirit-Projekt mithilfe des Skripts set_product_sku automatisch im Formular der Seite gespeichert.

4.3.2. Twig-Template

Das Twig-Template product-cms-block.twig entspricht Spryker-seitig einem Produkt-Absatz und erweitert das übergeordnete Template pdp.twig, in dem das Basis-Layout aller Produktseiten definiert ist. Es ist ein Bestandteil der in der Auslieferung enthaltenen zip-Datei b2c-demo-shop-extensions-<VERSION>.zip und muss Spryker-seitig unter dem Pfad src/Pyz/Yves/CmsBlockWidget/Theme/default/components/molecules/product-cms-block abgelegt werden.

Das Template pdp.twig erfordert folgende Anpassung, um die Einbindung des Produkt-Absatzes zu ermöglichen.

Anpassung des Twig-Templates pdp.twig
[...]
<div class="container__inner">
   {% include molecule('product-detail', 'ProductDetailPage') with {
      [...]
   } only %}

   {% include molecule('product-cms-block', 'CmsBlockWidget') ignore missing with {
      data: {
         idProductAbstract: data.product.idProductAbstract,
      }
   } only %}
</div>
[...]

Das folgende Code-Beispiel zeigt den Inhalt des Twig-Templates product-cms-block.twig. Es enthält zunächst den Namen des Moleküls und legt fest, dass die Angabe einer Product SKU erforderlich ist. Diese wird dem Twig-Template durch das übergeordnete Twig-Templates pdp.twig übergeben. Der Block body dient der Ausgabe der Inhalte, die für die entsprechende Produktseite gepflegt sind.

Twig-Template product-cms-block.twig
{% extends model('component') %}

{% define config = {
   name: 'product-cms-block'
} %}

{% define data = {
   idProductAbstract: required
} %}

{% block body %}
   {{ fsSpyCmsBlock({ product: data.idProductAbstract }) }}
{% endblock %}

4.4. Erzeugung dynamischer Inhaltsseiten

Zusätzlich zur Erweiterung bestehender statischer Seiten bzw. Kategorieseiten ermöglicht das FirstSpirit Connect for Spryker Commerce OS-Modul die Erzeugung dynamischer Inhaltsseiten. Diese entsprechen beispielsweise dem Impressum, der Datenschutzerklärung oder den allgemeinen Geschäftsbedingungen. Ebenso wie die übrigen Seiten lassen sich auch die dynamischen Inhaltsseiten mithilfe des Omnichannel Managers im ContentCreator darstellen und mit redaktionellen Inhalten anreichern. Da die dynamischen Seiten jedoch neu erstellt und nicht nur erweitert werden, sind sie im Gegensatz zu den anderen Seiten initial leer.

Für die Erzeugung der dynamischen Inhaltsseiten ist ebenfalls die Befüllung des Ausgabekanals der Seitenvorlage innerhalb des FirstSpirit-Projekts notwendig. Außerdem wird Spryker-seitig die Existenz des Twig-Templates fs-content-page.twig vorausgesetzt. Das Template ist ein Bestandteil der in der Auslieferung enthaltenen zip-Datei b2c-demo-shop-extensions-<VERSION>.zip.

Die im Referenzprojekt enthaltenen Absatzvorlagen sind für alle Seiten erlaubt. Aus diesem Grund sind keine zusätzlichen Erweiterungen erforderlich, die über die anhand des Shoppable Video-Absatzes bereits beschriebenen Anforderungen hinausgehen.

4.4.1. Seitenvorlage

Ebenso wie die Bearbeitung statischer Seiten und Kategorieseiten erfolgt die Pflege dynamischer Inhaltsseiten im FirstSpirit-Projekt auf Basis einer Seitenreferenz. Dynamische Inhaltsseiten werden jedoch im Gegensatz zu den anderen Seiten, die bereits im Projekt bestehen, über den bekannten Redaktionsprozess neu erzeugt. Aus diesem Grund sind sie initial leer.

Die Erzeugung der Seitenreferenz im ContentCreator stößt ein Event des Omnichannel Managers an, das die Spryker-seitige Erstellung der zugehörigen CMS Page auslöst. Dies ist für die Anzeige der CMS Page in der Vorschau notwendig.

Neue dynamische Inhaltsseiten müssen zwingend im Strukturordner Content Pages erstellt werden. Dies stellt ihre Speicherung in der richtigen CaaS-Collection und damit ihre automatische Erzeugung in Spryker sicher.

Unter bestimmten Umständen ist es möglich, dass das FirstSpirit-Projekt eine dynamische Inhaltsseite enthält, für die Spryker-seitig keine CMS Page existiert. In diesem Fall wird beim ersten Aufruf der Inhaltsseite im ContentCreator ebenfalls das Omnichannel Manager-Event angestoßen, das die Spryker-seitige Erstellung der zugehörigen CMS Page auslöst.

Das Referenzprojekt enthält die Seitenvorlage contentpage. Sie stellt ein Beispiel für dynamische Inhaltsseiten dar und bildet das Spryker-seitig anzulegende Twig-Template fs-content-page.twig ab.

Innerhalb des Ausgabekanals der Seitenvorlage erfolgt zunächst die Definition diverser allgemeiner Informationen und ihre Speicherung im JSON-Objekt des zu generierenden CaaS-Items: Die previewId dient der Identifikation der Seitenreferenz und ermöglicht deren Dekoration im ContentCreator sowie ihr Mapping auf das Spryker-seitige Twig-Template. Der automatisch ermittelte Name und der Pfad dieses Templates sind mithilfe der Felder template_name und template_path angegeben. Die Identifikation der Seitenreferenz für die Vorschau erfolgt über das JavaScript des Omnichannel Managers.

Zusätzlich zum Namen des Twig-Templates wird auch die Id der zugehörigen CMS Page automatisch ermittelt. Sie ist in einer versteckten Eingabekomponente der FirstSpirit-Seitenvorlage gespeichert. Da die Id nur für die Vorschau erforderlich ist und direkt aus dem Seitenformular ausgelesen wird, ist sie innerhalb des CaaS-Items nicht erforderlich.

Ergänzend dazu dient der pagetype der Definition des Seitentyps. Im Fall dynamischer Inhaltsseiten muss das Feld den Wert cmspage besitzen.

Die Felder is_active und store_names geben an, dass das durch die Seite repräsentierte Twig-Template Spryker-seitig aktiv und in dem in den Projekteinstellungen ausgewählten Store sichtbar ist. Über das Feld is_searchable ist außerdem konfigurierbar, ob die Seite Spryker-seitig über ihren Namen suchbar ist. Im Gegensatz zur previewId, die nur für die Vorschau dient, ermöglicht der eindeutige identifier auch die Spryker-seitige Referenzierung des CaaS-Items.

Definition allgemeiner Informationen im Ausgabekanal der Seitenvorlage
$CMS_SET(json, {:})$
$CMS_SET(previewId, previewId(element:#global.node))$
$CMS_SET(void, json.put("previewId", "" + previewId))$
$CMS_SET(void, json.put("template_name", pt_cmsPageTemplateName))$
$CMS_SET(void, json.put("template_path", "@Cms/templates/fs-content-page/fs-content-page.twig"))$
$CMS_SET(void, json.put("pagetype", "cmspage"))$
$CMS_SET(void, json.put("is_active", "1"))$
$CMS_SET(void, json.put("store_names", [ps_activeStore]))$
$CMS_SET(void, json.put("is_searchable", "1"))$
$CMS_SET(void, json.put("identifier", #global.node.uid))$

Zusätzlich zu den allgemeinen Informationen werden dem JSON-Objekt mithilfe des Arrays localizedAttributes spezifische Informationen übergeben, die Spryker für jede Inhaltsseite voraussetzt. Sie dienen der Definition verschiedener Metadaten sowie der Angabe eines Seitennamens und der URL, unter der die Seite Spryker-seitig erreichbar sein wird. Während die verschiedenen Metadaten optional vom Redakteur im Formular der Seite eintragbar sind, handelt es sich bei der URL um ein sprachabhängiges Pflichtfeld. Sie muss die Struktur /Language Abbreviation/Subpath besitzen, wobei das Sprachkürzel der URL während der Generierung automatisch vorangestellt wird. Der Importer erwartet diese Informationen im Kontext der aktuellen Sprache. Aus diesem Grund erfolgt eine Ermittlung des entsprechenden Sprachkürzels, das jedem Attribut mit übergeben wird.

Definition spezifischer Informationen
$CMS_SET(locale, #global.language.getLocale())$
$CMS_SET(localeAbbr, locale.getLanguage() + "_" + locale.getCountry())$

$CMS_SET(attributes, {:})$
$CMS_IF(pt_url != null && !pt_url.isEmpty())$
   $CMS_SET(url, "/" + locale.getLanguage() + if(!pt_url.startsWith("/"), "/") + pt_url.convert2)$
   $CMS_SET(void, attributes.put("url", {localeAbbr: url}))$
$CMS_ELSE$
   $CMS_SET(void,#global.logError(
      "Missing url for contentpage " + #global.node.uid + ". Contentpages without url can't create and generate."))$
   $CMS_SET(#global.stopGenerate,true)$
$CMS_END_IF$
$CMS_SET(pageName, #global.page.getDisplayName(#global.language))$
$CMS_SET(void, attributes.put("name", {localeAbbr: if(pageName.toString() != null, pageName, "")}))$
$CMS_SET(void, attributes.put("meta_title", {localeAbbr: if(!pt_metaTitle.isEmpty, pt_metaTitle.convert2, "")}))$
$CMS_SET(void, attributes.put("meta_description", {localeAbbr: if(!pt_metaDescription.isEmpty, pt_metaDescription.convert2, "")}))$
$CMS_SET(void, attributes.put("meta_keywords", {localeAbbr: if(!pt_metaKeywords.isEmpty, pt_metaKeywords.convert2, "")}))$
$CMS_SET(void, json.put("localizedAttributes", attributes))$

Die Seitenvorlage für dynamische Inhaltsseiten enthält die zwei Inhaltsbereiche content_top und content_body. Sie ermöglichen die Erzeugung redaktioneller Inhalte, wofür im Referenzprojekt verschiedene Absatzvorlagen zur Verfügung stehen. Ihre Inhalte werden nacheinander dem in der Vorlage erzeugten JSON-Objekt json hinzugefügt.

Ermittlung der redaktionellen Inhalte
$CMS_SET(blocks, [])$
$CMS_VALUE(#global.page.body("content_top"))$
$CMS_SET(contentTopBlocks, [])$
$CMS_SET(void, contentTopBlocks.addAll(blocks))$

$CMS_SET(blocks, [])$
$CMS_VALUE(#global.page.body("content_body"))$
$CMS_SET(contentBodyBlocks, [])$
$CMS_SET(void, contentBodyBlocks.addAll(blocks))$

$CMS_SET(resultingBlocks, [])$
$CMS_SET(void, resultingBlocks.addAll(contentTopBlocks))$
$CMS_SET(void, resultingBlocks.addAll(contentBodyBlocks))$
$CMS_SET(void, json.put("blocks", resultingBlocks))$

Im Gegensatz zu statischen Seiten und Kategorieseiten besitzen dynamische Inhaltsseiten sogenannte Placeholder. Diese entsprechen den Inhaltsbereichen der FirstSpirit-Seitenvorlage und enthalten Spryker-seitig lediglich Referenzen auf die ihnen zugeordneten CMS Blöcke. Im Anschluss an die Erfassung der redaktionellen Inhalte erfolgt daher für jeden Inhaltsbereich die Erzeugung dieser Referenzen.

Die Placeholder müssen auch im Fall leerer Inhaltsseiten erzeugt werden. Dies ist insbesondere für die initiale Erstellung der Seiten notwendig.

Erzeugung der Block-Referenzen
$CMS_SET(placeholder, {:})$
$CMS_SET(contentTopPlaceholder, "")$

$CMS_IF(!contentTopBlocks.isEmpty())$
   $CMS_FOR(contentTopBlock, contentTopBlocks)$
      $CMS_SET(contentTopPlaceholder, contentTopPlaceholder + "{{ fsSpyCmsBlock({name: '" + contentTopBlock.get("block_name") + "'}) }}\n")$
   $CMS_END_FOR$
$CMS_END_IF$

$CMS_SET(contentBodyPlaceholder, "")$
$CMS_IF(!contentBodyBlocks.isEmpty())$
   $CMS_FOR(contentBodyBlock, contentBodyBlocks)$
      $CMS_SET(contentBodyPlaceholder, contentBodyPlaceholder + "{{ fsSpyCmsBlock({name: '" + contentBodyBlock.get("block_name") + "'}) }}\n")$
   $CMS_END_FOR$
$CMS_END_IF$

$-- Placeholders values have to exist in Spryker for synchronization purposes, therefore allowing even empty placeholder values for online CaaS --$
$CMS_IF(!contentTopPlaceholder.isEmpty() || #global.isRelease())$
   $CMS_SET(void, placeholder.put("content_top", {localeAbbr: contentTopPlaceholder}))$
$CMS_END_IF$
$CMS_IF(!contentBodyPlaceholder.isEmpty() || #global.isRelease())$
   $CMS_SET(void, placeholder.put("content_body", {localeAbbr: contentBodyPlaceholder}))$
$CMS_END_IF$

$CMS_SET(void, json.put("placeholder", placeholder))$
$CMS_VALUE(json.toJSON)$

4.4.2. Twig-Template

Das Twig-Template fs-content-page.twig stellt Spryker-seitig eine dynamische Inhaltsseite dar. Diese besitzt im Gegensatz zu statischen Seiten und Kategorieseiten Placeholder. Um die Placeholder im ContentCreator bearbeitbar zu machen, ist für ihre Einbindung die Verwendung der Twig-Funktion fsSpyCms notwendig.

Jeder Placeholder repräsentiert einen Inhaltsbereich der entsprechenden FirstSpirit-Seitenvorlage. Aus diesem Grund müssen der Name des Placeholders und der Name des jeweiligen Inhaltsbereichs identisch sein. Jedem dieser Inhaltsbereiche lassen sich beliebig viele Absätze hinzufügen, für die Spryker-seitig ebenfalls ein Twig-Template existieren muss.

Die im Referenzprojekt enthaltene FirstSpirit-Seitenvorlage contentpage stellt ein Beispiel für dynamische Inhaltsseiten dar. Sie besitzt die Inhaltsbereiche content_top und content_body und bildet das Twig-Template fs-content-page.twig ab.

Innerhalb des Twig-Templates erfolgt zunächst die Definition spezifischer Metadaten sowie des Seitentitels. Anschließend erfolgt die Ausgabe der beiden Placeholder content_top und content_body in den Blöcken title und content. Sie referenzieren die ihnen zugeordneten CMS Blöcke, die ihrerseits die Ausgabe der redaktionellen Inhalte steuern.

Das folgende Code-Beispiel zeigt den Inhalt des Templates.

Twig-Template fs-content-page.twig
{% extends template('page-layout-main') %}

{% define data = {
   title: _view.pageTitle | default('global.spryker.shop' | trans),
   metaTitle: _view.pageTitle | default('global.spryker.shop' | trans),
   metaDescription: _view.pageDescription | default(''),
   metaKeywords: _view.pageKeywords | default('')
} %}

{% block breadcrumbs %}{% endblock %}

{% block title %}
   <!-- CMS_PLACEHOLDER : "content-top" -->
   <div class="cms-page__title">
      {{ fsSpyCms('content_top') | raw }}
   </div>
{% endblock %}

{% block content %}
   <!-- CMS_PLACEHOLDER : "content-body" -->
   <div class="cms-page__content">
      {{ fsSpyCms('content_body') | raw }}
   </div>
{% endblock %}

4.5. Erzeugung eines Magazins

Basierend auf den zuvor beschriebenen dynamischen Inhaltsseiten ermöglicht das FirstSpirit Connect for Spryker Commerce OS-Modul die Erstellung eines Magazins. Dieses setzt sich aus beliebig vielen Magazinartikeln und einer Übersichtsseite zusammen. Sowohl die Magazinartikel als auch die Übersichtsseite sind ebenso wie die übrigen Seiten im ContentCreator pflegbar. Im Gegensatz zu ihnen bilden die Magazinartikel jedoch nicht verschiedene Seiten, sondern einzelne Datenabsätze ab. Innerhalb des Referenzprojekts existiert für deren redaktionelle Erstellung und Pflege daher die Datenquelle Magazinartikel. Für die Ausgabe der Magazinartikel wird die zugehörige Tabellenvorlage in einer dynamischen Inhaltsseite referenziert. Die Referenzierung der Daten für die Übersichtsseite erfolgt über ContentSelects in einer Absatzvorlage, die ebenfalls in einer dynamischen Inhaltsseite eingebunden ist.

Die Erzeugung eines neuen Magazinartikels im ContentCreator stößt ein Event des Omnichannel Managers an, das die Spryker-seitige Erstellung der zugehörigen CMS Page auslöst. Dies ist für die Anzeige der CMS Page in der Vorschau notwendig.

Für die Erzeugung der Magazinartikel ist die Befüllung des Ausgabekanals der zugehörigen Seiten- und Tabellenvorlage notwendig. Die Übersichtsseite erfordert die Befüllung des Ausgabekanals der entsprechenden Absatzvorlage. Außerdem werden Spryker-seitig die Twig-Templates fs-magazine-intro.twig, fs-magazine-overview.twig, fs-magazine-teaser.twig und fs-content-page.twig vorausgesetzt. Die Templates sind ein Bestandteil des in der Auslieferung enthaltenen Spryker-Moduls firstspirit-reference-components.

Die übrigen im Referenzprojekt enthaltenen Absatzvorlagen zur Pflege redaktioneller Inhalte sind für alle Seiten erlaubt. Aus diesem Grund sind für sie keine zusätzlichen Erweiterungen erforderlich, die über die anhand des Shoppable Video-Absatzes bereits beschriebenen Anforderungen hinausgehen.

4.5.1. Seitenvorlage

Sowohl die Magazinartikel als auch die Übersichtsseite basieren auf dynamischen Inhaltsseiten. Da sie sich in ihrer Struktur unterscheiden, benötigen die Magazinartikel im Gegensatz zur Übersichtsseite jedoch eine eigene Seitenvorlage. Diese entspricht im Referenzprojekt der Seitenvorlage magazine_detail_page und stellt eine Kopie der contentpage dar. Im Vergleich zur contentpage besitzt die magazine_detail_page jedoch nur einen Inhaltsbereich, der ausschließlich die Einbindung der Tabellenvorlage der Magazinartikel erlaubt.

Der folgende Code-Ausschnitt zeigt den Ausgabekanal der Seitenvorlage magazine_detail_page:

Ausgabekanal der Seitenvorlage magazine_detail_page
$CMS_SET(json, {:})$
$CMS_IF(#global.pageParams.data.size > 0)$
   $CMS_SET(previewId, previewId(element:#global.node))$
   $CMS_SET(void, json.put("previewId", "" + previewId))$
   $CMS_SET(void, json.put("template_name", pt_cmsPageTemplateName))$
   $CMS_SET(void, json.put("template_path", "@Cms/templates/fs-content-page/fs-content-page.twig"))$
   $CMS_SET(void, json.put("pagetype", "cmspage"))$
   $CMS_SET(void, json.put("is_active", "1"))$
   $CMS_SET(void, json.put("store_names", [ps_activeStore]))$
   $CMS_SET(void, json.put("is_searchable", "1"))$

   $CMS_IF(#global.dataset.formData.tt_page_identifier != null && !#global.dataset.formData.tt_page_identifier.isEmpty())$
      $CMS_SET(void, json.put("identifier", #global.dataset.formData.tt_page_identifier))$
   $CMS_ELSE$
      $CMS_SET(void, #global.logError("Missing page identifier for magazine detail page with entity id '" + #row.id + "'. Magazine detail pages without a page identifier can't be generated."))$
      $CMS_SET(#global.stopGenerate, true)$
   $CMS_END_IF$

   $CMS_SET(locale, #global.language.getLocale())$
   $CMS_SET(localeAbbr, locale.getLanguage() + "_" + locale.getCountry())$

   $CMS_SET(attributes, {:})$
   $CMS_SET(set_entityUrl, #global.dataset.formData.tt_url.convert2)$
   $CMS_IF(set_entityUrl != null && !set_entityUrl.isEmpty())$
      $CMS_SET(url, "/" + locale.getLanguage() + if(!set_entityUrl.startsWith("/"), "/") + set_entityUrl)$
      $CMS_SET(void, attributes.put("url", {localeAbbr: url}))$
   $CMS_ELSE$
      $CMS_SET(void,#global.logError(
         "Missing url for contentpage " + #global.node.uid + "_" + global.dataset.entity.fs_id + ". Contentpages without url can't create and generate."))$
      $CMS_SET(#global.stopGenerate,true)$
   $CMS_END_IF$

   $CMS_SET(pageName, #global.dataset.formData.tt_title.convert2)$
   $CMS_SET(void, attributes.put("name", {localeAbbr: if(pageName.toString() != null, pageName, "")}))$
   $CMS_SET(void, attributes.put("meta_title", {localeAbbr: ""}))$
   $CMS_SET(void, attributes.put("meta_description", {localeAbbr: ""}))$
   $CMS_SET(void, attributes.put("meta_keywords", {localeAbbr: ""}))$
   $CMS_SET(void, json.put("localizedAttributes", attributes))$

   $CMS_VALUE(#global.page.body("container"))$
$CMS_END_IF$

$CMS_VALUE(json.toJSON)$

Der Ausgabekanal der Magazinartikel ist nahezu identisch mit dem dynamischer Inhaltsseiten. Er unterscheidet sich lediglich in den Angaben des Identifiers, einigen Attributen sowie der Anzahl der Inhaltsbereiche.

Der Identifier ermöglicht die Spryker-seitige Referenzierung des CaaS-Items und muss daher eindeutig sein. Würde er innerhalb des Ausgabekanals angegeben, besäßen jedoch alle Magazinartikel denselben Identifier. Aus diesem Grund ist er im Formular des entsprechenden Datensatzes gespeichert.

Anders als bei den dynamischen Inhaltsseiten erfolgt die Angabe der URL nicht im Formular der Seite, sondern ebenso wie der Identifier innerhalb des Datensatzes. Aus diesem Grund wird sie an dieser Stelle aus der Eingabekomponente des Datensatzes ermittelt. Für den Seitennamen wird die für den Magazinartikel definierte Überschrift herangezogen. Dies stellt sicher, dass jeder Magazinartikel einen eindeutigen Page Name besitzt.

Die umschließende If-Abfrage verhindert Generierungsfehler im Fall einer leeren Datenquelle.

Anders als bei den dynamischen Inhaltsseiten erfolgt die Ermittlung der redaktionellen Inhalte sowie die Erzeugung der Block-Referenzen für die Magazinartikel nicht innerhalb der Seitenvorlage, sondern im Ausgabekanal der zugehörigen Tabellenvorlage. Diese stellt den einzig zulässigen Inhalt für den Inhaltsbereich container dar.

Die Übersichtsseite entspricht einer dynamischen Inhaltsseite. Sie bindet die für sie notwendigen Daten mithilfe einer Absatzvorlage ein und erlaubt darüber hinaus die Ergänzung weiterer Absätze. Aus diesem Grund benötigt sie keine eigene Seitenvorlage.

4.5.2. Tabellenvorlage

Im Gegensatz zu den übrigen Seiten bilden die Magazinartikel einzelne Datensätze ab, die per Content Projection in einer Inhaltsseite eingebunden werden. Ihre Pflege und Bearbeitung erfolgt daher auf Basis einer Tabellenvorlage, die das entsprechende Formular bereitstellt und die Grundlage für die zugehörige Datenquelle bildet.

Die im Referenzprojekt enthaltene Tabellenvorlage magazine_articles gliedert sich thematisch in zwei Inhaltsblöcke:
Der erste Block bildet Spryker-seitig das Twig-Template fs-magazine-intro.twig ab und setzt sich aus übergeordneten Intro-Daten, wie beispielsweise einer Überschrift und verschiedenen Teaser-Informationen, zusammen. Für ihre Ermittlung wird innerhalb des Ausgabekanals der Tabellenvorlage die Formatvorlage magazine_intro_block_render_template referenziert, deren Ergebnis im Array contentTopBlocks gespeichert wird. Der Ausgabekanal dieser Formatvorlage ist nahezu identisch zum Ausgabekanal des Shoppable Video-Absatzes und unterscheidet sich lediglich in der Auswertung der zur Verfügung stehenden Eingabekomponenten.
Der zweite Block entspricht den einzelnen Absätzen der Magazinseite, die Spryker-seitig jeweils die ihnen zugehörigen Twig-Templates abbilden. Die Absätze sind in einem FS_CATALOG zusammengefasst, der im Ausgabekanal der Tabellenvorlage im Array contentBodyBlocks gespeichert wird.

Beide Arrays werden nacheinander dem in der Seitenvorlage erzeugten JSON-Objekt json hinzugefügt.

Ermittlung der redaktionellen Inhalte
$CMS_SET(blocks, [])$

$CMS_RENDER(template: "magazine_intro_block_render_template")$
$CMS_SET(contentTopBlocks, [])$
$CMS_SET(void, contentTopBlocks.addAll(blocks))$

$CMS_SET(blocks, [])$
$CMS_VALUE(tt_sections)$
$CMS_SET(contentBodyBlocks, [])$
$CMS_SET(void, contentBodyBlocks.addAll(blocks))$

$CMS_SET(resultingBlocks, [])$
$CMS_SET(void, resultingBlocks.addAll(contentTopBlocks))$
$CMS_SET(void, resultingBlocks.addAll(contentBodyBlocks))$
$CMS_SET(void, json.put("blocks", resultingBlocks))$

Da die Magazinartikel auf dynamischen Inhaltsseiten basieren, besitzen sie ebenfalls sogenannte Placeholder. Die Ausgabekanäle der Magazinartikel und der Inhaltsseiten sind daher ab diesem Punkt nahezu identisch. Sie unterscheiden sich lediglich in der Ausgabe des Placeholders für den Body-Bereich sowie in der Angabe der previewId. Im Gegensatz zu den Inhaltsseiten muss der Body-Bereich für die Magazinartikel auch in der Vorschau existieren, um die unerlaubte Ergänzung weiterer Absätze zu vermeiden. Die an dieser Stelle übergebene previewId überschreibt die Id der übergeordneten Seite, die alle Magazinartikel referenziert. Dies ist notwendig, da die previewId der Seite für alle Magazinartikel identisch ist, während die Ids der Artikel eindeutig sind.

Erzeugung der Block-Referenzen
$CMS_SET(placeholder, {:})$
$CMS_SET(contentTopPlaceholder, "")$

$CMS_IF(!contentTopBlocks.isEmpty())$
   $CMS_FOR(contentTopBlock, contentTopBlocks)$
      $CMS_SET(contentTopPlaceholder, contentTopPlaceholder + "{{ fsSpyCmsBlock({name: '" + contentTopBlock.get("block_name") + "'}) }}\n")$
   $CMS_END_FOR$
$CMS_END_IF$

$CMS_SET(contentBodyPlaceholder, "")$
$CMS_IF(!contentBodyBlocks.isEmpty())$
   $CMS_FOR(contentBodyBlock, contentBodyBlocks)$
      CMS_SET(contentBodyPlaceholder, contentBodyPlaceholder + "{{ fsSpyCmsBlock({name: '" + contentBodyBlock.get("block_name") + "'}, isContentEditable = false) }}\n")$
   $CMS_END_FOR$
$CMS_END_IF$

$-- Placeholders values have to exist in Spryker for synchronization purposes, therefore allowing even empty placeholder values for online CaaS --$
$CMS_IF(!contentTopPlaceholder.isEmpty() || #global.isRelease())$
   $CMS_SET(void, placeholder.put("content_top", {localeAbbr: contentTopPlaceholder}))$
$CMS_END_IF$
$CMS_SET(void, placeholder.put("content_body", {localeAbbr: contentBodyPlaceholder}))$

$CMS_SET(void, json.put("placeholder", placeholder))$
$CMS_SET(void, json.put("previewId", "" + previewId()))$

4.5.3. Absatzvorlage

Zusätzlich zu den einzelnen Magazinartikeln existiert eine Übersichtsseite, auf der die Artikel in Form von Teasern auf- oder absteigend nach einem Datum sortiert aufgelistet werden. Anders als bei den Magazinartikeln erfolgt die Ausgabe der redaktionellen Inhalte jedoch nicht über eine Content Projection, sondern über zwei ContentSelects. Das Referenzprojekt enthält daher die Absatzvorlage magazine_overview, die ausschließlich in dynamischen Inhaltsseiten verwendbar ist.

Die Bearbeitung, Löschung oder Erzeugung eines Magazinartikels erzeugt standardmäßig keine Aktualisierung der Übersichtsseite in der Vorschau. Innerhalb des Referenzprojekts enthält die Absatzvorlage magazine_overview aus diesem Grund die versteckte FS_REFERENCE-Eingabekomponente st_dataSource. In dieser ist als Vorgabewert die Datenquelle magazine_articles eingetragen, die alle Magazinartikel enthält. Mithilfe dieser Angabe erkennt ein im Hintergrund laufender Service die Abhängigkeit zwischen dem entsprechenden Magazinartikel und der Übersichtsseite und stößt deren Aktualisierung in der Vorschau an.

Die Publikation eines Magazinartikels bewirkt immer auch eine Publikation der Übersichtsseite. Dies stellt sicher, dass die Übersichtsseite stets aktuell ist und im Live-Stand jederzeit alle veröffentlichten Magazinartikel enthält.

Der Ausgabekanal der Absatzvorlage enthält an erster Stelle die ContentSelects. Diese fragen alle Datensätze der Datenquelle magazine ab und speichern sie in unterschiedlicher Sortierung in den Variablen fr_st_teasers_descending bzw. fr_st_teasers_ascending.

ContentSelects im Ausgabekanal des Absatzes
<CMS_HEADER>
   <CMS_FUNCTION name="contentSelect" resultname="fr_st_teasers_descending">
      <CMS_PARAM name="schema" value="magazine" />
      <QUERY entityType="magazine_articles">
         <ORDERCRITERIA attribute="date" descending="1" />
      </QUERY>
   </CMS_FUNCTION>

   <CMS_FUNCTION name="contentSelect" resultname="fr_st_teasers_ascending">
      <CMS_PARAM name="schema" value="magazine" />
      <QUERY entityType="magazine_articles">
         <ORDERCRITERIA attribute="date" descending="0" />
      </QUERY>
   </CMS_FUNCTION>
</CMS_HEADER>

Der nächste Schritt umfasst die Definition diverser Informationen, die auch in allen anderen Absätzen des Referenzprojekts enthalten sind. Der Ausgabekanal ist daher an dieser Stelle zu dem des Shoppable Video-Absatzes identisch.

Definition diverser Informationen im Ausgabekanal des Absatzes
$CMS_SET(block,{:})$

$-- Defining general block data --$
$CMS_SET(void, block.put("previewId", "" + previewId()))$
$CMS_SET(void, block.put("active", "1"))$
$CMS_SET(void, block.put("store_names", [ps_activeStore]))$
$CMS_SET(void, block.put("template_name", "fs_molecule_block"))$
$CMS_SET(void, block.put("template_path", "@CmsBlock/template/fs_molecule_block.twig"))$

$CMS_SET(set_pageType, json.get("pagetype"))$

$-- Add block name attribute to block object (page type dependent) --$
$CMS_RENDER(template: "block_name_render", rt_pageType: set_pageType, rt_blockObject: block)$

$-- Add additional block attributes to block object (page type dependent) --$
$CMS_RENDER(template: "additional_block_attributes_render", rt_pageType: set_pageType, rt_blockObject: block)$

$-- Add block key attribute to block object (page type dependent) --$
$CMS_RENDER(template: "block_key_render", rt_pageType: set_pageType, rt_blockObject: block)$

$-- Defining placeholder data of the block --$
$CMS_SET(placeholders,{:})$
$CMS_SET(void, block.put("placeholder",placeholders))$

Daran anschließend erfolgt in zwei Schritten die Ermittlung der Teaser-Informationen. Sie setzen sich aus einem Titel, einem Bild, einem Text und einem Verweis zusammen und werden pro Datensatz im Array teaser gespeichert.

Ist für einen Teaser kein Titel angegeben bzw. kein Bild ausgewählt, werden der Titel und das Bild des zugehörigen Magazinartikels für die Darstellung auf der Magazinübersichtsseite verwendet. Sind die Felder an beiden Stellen gepflegt, zeigt die Übersichtsseite stets die Inhalte des Teasers an.

Der erste Schritt berücksichtigt ausschließlich die Informationen der Featured Article, die sich im Formular der Übersichtsseite definieren lassen. Der zweite Schritt basiert auf der Ergebnismenge des entsprechenden ContentSelects und umfasst somit jeweils alle Magazinartikel. In beiden Fällen wird die Formatvorlage magazine_teaser_render referenziert, deren Ausgabekanal lediglich die Auswertung der für die Teaser zur Verfügung stehenden Eingabekomponenten beinhaltet. Die in den beiden Schritten ermittelten Informationen werden in den Arrays featuredTeasers und teasers gespeichert.

Ermittlung der Teaser-Daten im Ausgabekanal des Absatzes
$CMS_SET(featuredTeasers, [])$
$CMS_FOR(for_featuredArticle, st_featuredArticles.values)$
   $CMS_SET(teaser,{:})$
   $CMS_RENDER(template: "magazine_teaser_render", rt_entity: for_featuredArticle.entity, rt_teaser: teaser)$
   $CMS_SET(void, featuredTeasers.add(teaser))$
$CMS_END_FOR$

$CMS_SET(teasers, [])$
$CMS_FOR(for_teaser, #global.context.getVariableValue("fr_st_teasers_"+st_sortingOrder.key))$
   $CMS_SET(teaser,{:})$
   $CMS_RENDER(template: "magazine_teaser_render", rt_entity: for_teaser, rt_teaser: teaser)$
   $CMS_SET(void, teasers.add(teaser))$
$CMS_END_FOR$

Das Array data beinhaltet die redaktionellen Inhalte. Ihm werden die zuvor ermittelten Teaser-Daten hinzugefügt. Der Absatz wird Spryker-seitig durch das Molekül fs-magazine-overview repräsentiert, dessen Name ebenfalls im data-Array enthalten ist.

Der Importer erwartet die Informationen im Kontext der aktuellen Sprache. Aus diesem Grund erfolgt eine Ermittlung des entsprechenden Sprachkürzels, dem das Array data zugeordnet wird.

Im Vorschaufall werden die Inhalte des Absatzes anschließend direkt ausgegeben. Andernfalls fügt der letzte Schritt den Absatz dem in der Seitenvorlage definierten Array blocks hinzu, das alle Absätze einer Seite enthält und sie in das zu generierende CaaS-Item integriert. Da die Übersichtsseite auf einer dynamischen Inhaltsseite basiert, handelt es sich bei der zugehörigen Seitenvorlage um die contentpage.

Verarbeitung der redaktionellen Inhalte im Ausgabekanal des Absatzes
$CMS_SET(data, {:})$
$CMS_SET(void, data.put("moleculename", "fs-magazine-overview"))$
$CMS_SET(void, data.put("featuredTeasers", featuredTeasers))$
$CMS_SET(void, data.put("teasers", teasers))$

$CMS_SET(locale, #global.language.getLocale())$
$CMS_SET(localeAbbr, locale.getLanguage() + "_" + locale.getCountry())$
$CMS_SET(localizedData, {:})$
$CMS_SET(void, localizedData.put(localeAbbr, data))$
$CMS_SET(void, block.put("data", localizedData))$

$CMS_IF(#global.is("WEBEDIT") && !isSet(caas_preview_generation))$
   $CMS_VALUE(block.toJSON)$
$CMS_ELSE$
   $CMS_SET(void, blocks.add(block))$
$CMS_END_IF$

4.5.4. Twig-Templates

Sowohl die Magazinartikel als auch die Übersichtsseite basieren auf dynamischen Inhaltsseiten und werden daher Spryker-seitig durch das Twig-Template fs-content-page.twig dargestellt. Dieses enthält die Placeholder content_top und content_body, welche die ihnen zugeordneten CMS Blöcke referenzieren. Auf diesem Weg werden für die Intro-Daten der Magazinartikel das Molekül fs-magazine-intro.twig und für die Teaser-Informationen der Übersichtsseite das Molekül fs-magazine-overview.twig aufgerufen. Das Molekül fs-magazine-overview.twig referenziert seinerseits das Molekül fs-magazine-teaser.twig, das die Teaser-Informationen eines einzelnen Magazinartikels bereitstellt. Alle drei Moleküle steuern ihrerseits die Ausgabe der redaktionellen Inhalte.

Die Ausgabe der übrigen Absätze der Magazinartikel erfolgt über die ihnen zugehörigen Twig-Templates. Sowohl die Templates dieser Absätze als auch die Moleküle für die Magazinartikel und die Übersichtsseite sind ein Bestandteil des in der Auslieferung enthaltenen Spryker-Moduls firstspirit-reference-components.

Ebenso wie bei den Molekülen des Shoppable Video-Absatzes und des Banners wird innerhalb der drei Twig-Templates für die Magazinartikel und die Übersichtsseite zunächst der Name des Moleküls definiert und anschließend das fsBlockData-Objekt erzeugt. Es ermöglicht den Zugriff auf die strukturierten Daten, die im Ausgabekanal der FirstSpirit-Tabellenvorlage definiert sind. Das fsBlockData-Objekt und das FirstSpirit-seitige JSON-Objekt besitzen somit jeweils dieselbe Struktur.

Der Block body beschreibt in den Molekülen jeweils die Ausgabe der redaktionellen Inhalte. Diese entsprechen im Template für die Magazinartikel deren Intro-Daten, die sich aus einem Titel, einem Subtitel und einem Banner zusammensetzen. Im Template für die Übersichtsseite handelt es sich um die Teaser-Daten der Magazinartikel, die aus einem Bild, einem Titel, einem Text und einem Verweis bestehen und mithilfe des Moleküls für die Teaser bereitgestellt werden.

Die folgenden Code-Beispiele zeigen die Inhalte der Moleküle.

Twig-Template fs-magazine-intro.twig
{% extends model('component') %}

{% define config = {
    name: 'fs-magazine-intro'
} %}

{% define data = {
    fsBlockData: [],
} %}

{% block body %}
   <article class="magazine">
      <header>
         <h1>{{ data.fsBlockData.title }}</h1>
         {% if data.fsBlockData.subtitle is defined %}
            <h2>{{ data.fsBlockData.subtitle }}</h2>
         {% endif %}
         {% if data.fsBlockData.banner.imageUrl is defined %}
            <figure class="picture picture-responsive">
               <img class="img-fluid" src="{{ data.fsBlockData.banner.imageUrl | raw }}"
                  {% if  data.fsBlockData.banner.previewId is defined %}
                     data-preview-id="{{ data.fsBlockData.banner.previewId }}"
                  {% endif %}
                  data-tpp-context-image-resolution="MAGAZINE_ARTICLE_BANNER">
            </figure>
         {% endif %}
      </header>
   </article>
{% endblock %}
Twig-Template fs-magazine-overview.twig
{% extends model('component') %}

{% define config = {
    name: 'fs-magazine-overview'
} %}

{% define data = {
    fsBlockData: [],
} %}

{% block body %}
   {% if isFsPreview() %}
      <div style="padding-top: 24px;"></div>
   {% endif %}
   {% if data.fsBlockData.featuredTeasers is not empty %}
      <h2 style="text-align: left;">Featured</h2>
   {% endif %}

   <div class="featured-magazine-teasers">
      {% for teaser in data.fsBlockData.featuredTeasers %}
         {% include molecule('fs-magazine-teaser', 'FirstSpiritReferenceComponents') with {
            data: {
               fsBlockData: teaser
            }
         } only %}
      {% endfor %}
   </div>

   {% if data.fsBlockData.featuredTeasers is not empty %}
      <hr class="magazine-featured-divider">
   {% endif %}

   <div class="magazine-teasers">
      {% for teaser in data.fsBlockData.teasers %}
         {% include molecule('fs-magazine-teaser', 'FirstSpiritReferenceComponents') with {
            data: {
               fsBlockData: teaser
            }
         } only %}
      {% endfor %}
   </div>
{% endblock %}
Twig-Template fs-magazine-teaser.twig
{% extends model('component') %}

{% define config = {
   name: 'fs-magazine-teaser'
} %}

{% define data = {
   fsBlockData: [],
} %}

{% block body %}
   <article class="magazine-teaser"
      {% if data.fsBlockData.previewId is defined %}
         data-preview-id="{{ data.fsBlockData.previewId }}"
      {% endif %}>
      {% set cmsPageUrl = getCmsPageUrl(data.fsBlockData.page_identifier) %}

      {% if cmsPageUrl is not null %}
         <a href="{{ cmsPageUrl }}">
      {% endif %}

         {% if data.fsBlockData.picture.imageUrl is defined %}
            <figure class="picture picture-responsive">
               <img src="{{ data.fsBlockData.picture.imageUrl }}"
                  {% if  data.fsBlockData.picture.previewId is defined %}
                     data-preview-id="{{ data.fsBlockData.picture.previewId }}"
                  {% endif %}
                  data-tpp-context-image-resolution="CONTENT_IMAGE">
            </figure>
         {% endif %}
         <h3>{{ data.fsBlockData.title | raw }}</h3>
         <p>{{ data.fsBlockData.text | raw }}</p>

      {% if cmsPageUrl is not null %}
         </a>
      {% endif %}
   </article>
{% endblock %}

4.6. Erweiterung der Hauptnavigation

Neben den unterschiedlichen Seitentypen lässt sich auch die Hauptnavigation des Spryker B2C Demo Shops im ContentCreator bearbeiten. Sie wird in FirstSpirit über eine globale Seite, eine Absatzvorlage sowie eine technische Seitenreferenz abgebildet. Diese ermöglichen die Erzeugung weiterer Menüpunkte in der ersten Ebene der Navigation sowie deren Übertragung in den Preview CaaS und in den Online CaaS.

Um die Erweiterbarkeit der Hauptnavigation zu ermöglichen, ist darüber hinaus eine Anpassung der folgenden Twig-Templates erforderlich:

  • navigation-header.twig

  • navigation-multilevel-node.twig

4.6.1. Globale Seite

Die Navigationen des Spryker B2C Demo Shops werden in FirstSpirit über die Seitenvorlage navigation_extension abgebildet, auf deren Basis pro Navigation automatisch eine globale Seite erzeugt wird. Sie besitzt eine FS_CATALOG-Eingabekomponente, die mithilfe der Absatzvorlage navigation_node_reference die Startknoten aller in FirstSpirit gepflegten Menüpunkte referenziert. Jeder dieser Startknoten entspricht einem Strukturordner, der innerhalb eines Bearbeitungsdialogs im ContentCreator auszuwählen ist. Dafür besitzt die Hauptnavigation im ContentCreator einen Button, der die Ergänzung neuer Menüpunkte in der ersten Ebene der Navigation ermöglicht. Enthält ein referenzierter Strukturordner weitere Unterordner, werden diese automatisch als Unterpunkte des neuen Menüpunkts interpretiert.

Der Button zur Ergänzung weiterer Menüpunkte ist lediglich für die Rollen sichtbar, die das Bearbeiten- und Löschen-Recht besitzen. Andernfalls ist der Button ausgeblendet.

img navigation
Abbildung 28. Button zur Erweiterung der Navigation

4.6.2. Absatzvorlage

Die im Referenzprojekt enthaltene globale Seite navigation_extension ermöglicht die Erweiterung der Hauptnavigation im ContentCreator. Der Navigation lassen sich Menüpunkte in der ersten Ebene hinzufügen, die jeweils einem Strukturordner entsprechen und als Startknoten dienen. Die Unterordner eines solchen Strukturordners werden automatisch als Unterpunkte des neuen Menüpunkts interpretiert.

Für alle neuen Startknoten wird der FS_CATALOG-Eingabekomponente der globalen Seite jeweils ein auf der Absatzvorlage navigation_node_reference basierender Eintrag hinzugefügt. Die Absatzvorlage enthält ihrerseits eine FS_REFERENCE-Eingabekomponente, die der Referenzierung des jeweiligen Menüpunkts dient.

In ihrem Ausgabekanal enthält die Absatzvorlage darüber hinaus die Navigationsfunktion fr_mainNav. Ausgehend vom ausgewählten Strukturordner erzeugt diese Funktion für ihn und die in ihm enthaltenen Unterordner die Teilnavigation für den neuen Menüpunkt. Alle diese Teilnavigationen der einzelnen Menüpunkte werden mithilfe der technischen Seitenvorlage navigations zusammengefasst und an den CaaS übertragen.

4.6.3. Seitenvorlage

Zusätzlich zur globalen Seite enthält das Referenzprojekt die technische Seitenreferenz navigations. Diese dient der Übertragung aller in FirstSpirit durchgeführten Navigationsänderungen in den CaaS.

Mithilfe des Skripts get_navigation_gca_pages ermittelt die Seitenreferenz alle globalen Seiten, die auf der Seitenvorlage navigation_extension basieren. Die globalen Seiten bilden die über den ContentCreator erweiterbaren Navigationen in FirstSpirit ab. Innerhalb des Referenzprojekts handelt es sich dabei um die Hauptnavigation des Spryker B2C Demo Shops.

Jede dieser globalen Seiten enthält eine FS_CATALOG-Eingabekomponente, die mithilfe der Absatzvorlage navigation_node_reference die Startknoten aller in FirstSpirit gepflegten Menüpunkte referenziert. Die Absatzvorlage erzeugt ihrerseits für jeden dieser Startknoten eine Teilnavigation. Die technische Seitenreferenz fasst alle diese Teilnavigationen zusammen und erzeugt ein JSON-Dokument, in dem alle in FirstSpirit erweiterbaren Navigationen enthalten sind.

Für die Freigabe der vorgenommenen Navigationsänderungen stellt das Referenzprojekt den Arbeitsablauf Freigabe der Navigation bereit, für dessen Ausführung das Freigabe-Recht erforderlich ist. Der Arbeitsablauf führt lediglich die Freigabe, jedoch keine Publikation der zugehörigen globalen Seite durch. Gleichzeitig stößt er ein Skript an, das die Übertragung der technischen Seitenreferenz in den Preview CaaS sicherstellt. Die Publikation der Anpassungen und ihre Übertragung in den Online CaaS erfolgt erst im Rahmen einer Vollgenerierung.

4.6.4. Twig-Templates

Zusätzlich zu den beschriebenen Vorlagen in FirstSpirit wird Spryker-seitig die Anpassung der folgenden Twig-Templates vorausgesetzt, um die Erweiterung der Hauptnavigation des Spryker B2C Demo Shops im ContentCreator zu ermöglichen.

  • navigation-header.twig

  • navigation-multilevel-node.twig

Die durchzuführenden Anpassungen sind Teil der Installation und werden daher an dieser Stelle nicht beschrieben.

Die Twig-Templates bilden Spryker-seitig die Hauptnavigation ab. Sie referenzieren die einzelnen Menüpunkte und steuern ihre Darstellung in der Vorschau und im Live-Stand. Mithilfe der Anpassungen erhält die Hauptnavigation im ContentCreator einen Button, der die Ergänzung weiterer Menüpunkte ermöglicht.

Besteht der Wunsch, andere Navigationen im ContentCreator zu bearbeiten, ist ausschließlich eine Anpassung der zugehörigen Twig-Templates erforderlich. Das Kapitel Navigationspflege erläutert die dafür notwendigen Schritte.

Die FirstSpirit-seitig gepflegten, redaktionellen Inhalte können die nachfolgenden Verweise enthalten, die sie mit anderen Inhalten verknüpfen. Sie basieren auf Verweisvorlagen, die im Referenzprojekt bereits enthalten sind.

Alle Verweisvorlagen sind jeweils doppelt vorhanden, da sie sich in der Art ihrer Einbindung unterscheiden: Im Gegensatz zu den allgemeinen Verweisen können die DOM-Verweise - ihrem Namen entsprechend - nur innerhalb von DOM-Editor verwendet werden.

Kategorie- und Produktverweis

Das FirstSpirit Connect for Spryker Commerce OS-Modul stellt im ContentCreator jeweils einen Report für Produkte und Kategorien bereit. Sie dienen der Darstellung der aus Spryker stammenden Kategorie- und Produktinformationen, die sich für Verweise auf Kategorie- bzw. Produktdetailseiten verwenden lassen.

Das Referenzprojekt enthält dafür die Verweisvorlagen category_link und product_link bzw. dom_category_link und dom_product_link, die einem Kategorie- bzw. Produktverweis entsprechen. Sie ermöglichen die Referenzierung von Kategorie- bzw. Produktdetailseiten und sind jeweils äquivalent zueinander.

Im Gegensatz zu einer Kategorie wird ein referenziertes Produkt anhand seiner Sku und nicht anhand der Node-Id identifiziert.

Inhaltsseitenverweis

Die im Referenzprojekt enthaltenen Verweisvorlagen content_link und dom_content_link entsprechen einem Inhaltsseitenverweis. Dieser ermöglicht die Referenzierung statischer Seiten sowie dynamischer Inhaltsseiten, die innerhalb des FirstSpirit-Projekts gepflegt sind. Im Referenzprojekt ist die Auswahl des Verweisziels daher auf Seitenreferenzen im Strukturordner content_pages eingeschränkt.

Für Redakteure ist es nicht ersichtlich, ob es sich bei einem Verweisziel um eine dynamische Inhaltsseite oder eine statische Seite handelt. Da statische Seiten jedoch standardmäßig keine URL besitzen, wären Verweise auf sie generell nicht möglich. Die Projekteinstellungen stellen daher eine Möglichkeit bereit, ihnen eine URL zuzuweisen. Die im Referenzprojekt vorgenommenen technischen Anpassungen sind im nachfolgenden Unterkapitel beschrieben.

Magazinartikelverweis

Das Referenzprojekt besitzt die Verweisvorlagen magazine_article_link und dom_magazine_article_link, die einem Magazinartikelverweis entsprechen. Ebenso wie der Inhaltsseitenverweis ermöglicht er die Referenzierung redaktioneller Inhalte, die innerhalb des FirstSpirit-Projekts gepflegt sind. Im Gegensatz zu diesem bezieht sich der Magazinartikelverweis jedoch seinem Namen entsprechend auf Magazinartikel.

Externer Verweis

Ebenso wie der zuvor beschriebene Inhaltsseitenverweis bzw. Magazinartikelverweis ermöglicht der externe Verweis die Referenzierung redakioneller Inhalte. Im Gegensatz zu diesen bezieht er sich jedoch ausschließlich auf externe Inhalte.

Suchverweis

Das Referenzprojekt enthält die Verweisvorlagen search_link und dom_search_link, die einem Suchverweis entsprechen. Dieser ermöglicht die Verlinkung einer Suchergebnisseite zu einem definierten Suchbegriff.

Alle Verweisvorlagen der DOM-Verweise enthalten in ihrem Ausgabekanal einen Aufruf des zugehörigen Widgets, das die Ausgabe des Verweises Spryker-seitig steuert. Auf diesem Weg wird das HTML für den Verweis automatisch erzeugt. Eine projektspezifische Anpassung des HTMLs ist nicht möglich.

Widget-Aufruf innerhalb des DOM-Kategorieverweises
{% widget 'FirstSpiritCategoryLinkWidget' args [$CMS_VALUE(lt_category.values[0].getNodeId)$, "$CMS_VALUE(lt_linkText.convert2)$"] only %}{% endwidget %}

Im Gegensatz dazu enthalten die Verweisvorlagen der allgemeinen Verweise lediglich die Definition zweier Parameter. Sie folgen damit demselben Konzept wie die Seiten- und Absatzvorlagen. Auf diesem Weg wird lediglich die URL des Verweises erzeugt und das HTML ist Spryker-seitig frei definierbar.

Parameterdefinition innerhalb des Kategorieverweises
$CMS_SET(set_id)$
   $CMS_VALUE(lt_category.values[0].getNodeId)$
$CMS_END_SET$
$CMS_SET(void, set_link.put("id", set_id.toString()))$
$CMS_SET(void, set_link.put("type","category"))$

Die Verarbeitung der allgemeinen Verweise steuert das Twig-Template link.twig, das Bestandteil des FirstSpiritPreview-Moduls ist und die entsprechende URL auf Basis des Verweistyps ermittelt.

Twig-Template link.twig
{% define data = {link: link} %}
{%- if data.link.type is defined -%}
   {%- set type = data.link.type -%}
   {%- if data.link.id is defined and data.link.id is not empty -%}
      {%- set id = data.link.id -%}
      {%- if  type == "cmspage" -%}
         {%- set url = getCmsPageUrl(id) -%}
      {%- elseif type == "category" -%}
         {%- set url = getCategoryPageUrl(id) -%}
      {%- elseif type == "product" -%}
         {%- set url = getProductPageUrl(id) -%}
      {%- endif -%}
   {%- else -%}
      {%- if type == "search" -%}
         {%- set url = path('search') ~ '?q=' ~ data.link.query -%}
      {%- elseif type == "external" -%}
         {%- set url = data.link.url -%}
      {%- elseif type == "static" -%}
         {%- set url = data.link.url -%}
      {%- endif -%}
   {%- endif -%}
{%- endif -%}

{%- if url is defined and url is not null -%}
   {{- url -}
}{%- endif -%}

Der Aufruf des Twig-Templates erfolgt in den einzelnen Komponenten, die Spryker-seitig die FirstSpirit-Absätze repräsentieren:

Beispielaufruf des Twig-Templates link.twig
 <a href="{% include template('link', 'FirstSpiritPreview') with { link: data.fsBlockData.link } %}">

Alternativ dazu lassen sich die Twig-Funktionen zur Ermittlung der allgemeinen Verweise auch direkt aufrufen:

Aufrufe der Twig-Funktionen für die Ermittlung der allgemeinen Verweise
{% set url = getCmsPageUrl(cms_page_id) %}
{% set url = getProductPageUrl(productId) %}
{% set url = getCategoryPageUrl(categoryId) %}

Bei der Erstellung von Inhaltsseitenverweisen ist Redakteuren kein Unterschied zwischen statischen und dynamischen Seiten ersichtlich. Da statische Seiten jedoch standardmäßig keine URL besitzen, wäre ihre Referenzierung generell nicht möglich. Die Projekteinstellungen stellen daher eine Möglichkeit bereit, ihnen eine URL zuzuweisen. Sie besitzen dafür den FS_CATALOG ps_staticLinks, der mithilfe des Buttons Statische Seiten Templates Import befüllt wird.

Eine spätere Änderung der in den Projekteinstellungen definierten URLs erfordert sowohl die Ausführung der Vollgenerierung als auch der Vorschaugenerierung.

Der Button Statische Seiten Templates Import führt die Executable ProjectPropertiesStaticPageUrlListExecutable aus, die den Inhalt des Vorlagenordners static_pages ermittelt. Für jede in dem Ordner enthaltene Vorlage fügt sie dem FS_CATALOG einen Eintrag auf Basis der technischen Absatzvorlage static_page_url hinzu. Jeder dieser Einträge besitzt eine Referenz auf die jeweilige Vorlage sowie ein sprachabhängiges Feld für die zu definierende relative URL.

Für die Erzeugung der Einträge und die automatische Referenzierung der Vorlagen innerhalb dieser Einträge besitzt der Button die folgenden Parameter, die innerhalb des Referenzprojekts entsprechend vordefiniert sind:

  • staticPageCatalog: Für die automatische Erstellung der Einträge definiert dieser Parameter die FS_CATALOG-Komponente in den Projekteinstellungen.

  • staticPageUrlTemplateUid: Dieser Parameter gibt den Referenznamen der technischen Absatzvorlage an, auf deren Basis die Einträge im FS_CATALOG erzeugt werden.

  • staticPageTemplateFolder: Dieser Parameter definiert den Referenznamen des Vorlagenordners, der alle Vorlagen für statische Seiten enthält.

  • pageTemplateFsReference: Für die automatische Referenzierung der Vorlagen ist diesem Parameter der Name der FS_REFERENCE-Komponente aus der technischen Absatzvorlage zugewiesen.

Um Inhaltsseitenverweise auf statische Seiten zu ermöglichen, müssen die in den Projekteinstellungen definierten URLs in den Verweisvorlagen verfügbar sein. Der Ausgabekanal der Projekteinstellungen enthält daher den folgenden Code, mit dem die URL einer Vorlage jeweils in der Variablen set_ps_staticLinks gespeichert wird.

Ausgabekanal der Projekteinstellungen
$CMS_SET(set_ps_staticLinks,{:})$
$CMS_FOR(for_staticLink,ps_staticLinks.filter(x->!x.item.st_pageTemplate.isEmpty))$
   $CMS_SET(void, set_ps_staticLinks
      .put(
         for_staticLink.item.st_pageTemplate.get.uid,
         for_staticLink.item.st_url.convert2
      )
   )$
$CMS_END_FOR$
$CMS_SET(set_ps_contentPageList,["contentpage"])$

Innerhalb des Referenzprojekts wird die Variable im Ausgabekanal des Inhaltsseitenverweises abgefragt. Auf diesem Weg müssen Redakteure bei der Auswahl eines Verweisziels nicht zwischen statischen und dynamischen Inhaltsseiten unterscheiden können.

Code-Ausschnitt des Inhaltsseitenverweises
$CMS_SET(set_pageUid,lt_pageRef.get().page.template.uid)$
$CMS_IF(set_pageUid == "contentpage")$
[...]
$CMS_ELSIF(!set_ps_staticLinks.isEmpty)$
   $CMS_IF(set_ps_staticLinks.containsKey(set_pageUid) && !set_ps_staticLinks.get(set_pageUid).isEmpty)$
      $CMS_SET(void, set_link.put("url", set_ps_staticLinks.get(set_pageUid)))$
      $CMS_SET(void, set_link.put("type","static"))$
      [...]
   $CMS_END_IF$
   [...]
$CMS_END_IF$

5. Anwendungsfälle

Innerhalb des Verlauf eines Projekts können unterschiedliche Situationen auftreten, die bestimmte Handlungsschritte erfordern. Die nachfolgenden Unterkapitel stellen Situationen dar, die typischerweise in Integrationsprojekten vorkommen können, und beschreiben anhand des mitgelieferten Referenzprojekts die notwendigen Schritte für ihre Auflösung.

5.1. Inhaltsabgleich

Die Integration setzt voraus, dass die Datenbestände innerhalb des FirstSpirit-Projekts, der jeweiligen CaaS-Instanz und in Spryker konsistent zueinander sind. Durch die folgenden Situationen, die während des Projektverlaufs auftreten können, wird diese Konsistenz jedoch systembedingt verletzt:

Projektübertragung auf eine neue Deployment-Umgebung (Dev, Prod, QA)

Die Erzeugung einer neuen Deployment-Umgebung beinhaltet stets den Import eines bestehenden FirstSpirit-Projekts. Durch den Import entsteht eine Konstellation, in der FirstSpirit-seitig bereits Inhalte existieren, während die CaaS-Instanzen und Spryker leer sind oder abweichende Inhalte besitzen.

ContentTransport

Im Gegensatz zum vorherigen Punkt, bei dem vollständige Projekte in eine andere Deployment-Umgebung transferiert werden, dient der ContentTransport der Übertragung redaktioneller Inhalte zwischen zwei Projekten. Während des Projektverlaufs lassen sich auf diesem Weg beispielsweise die Inhalte der Produktivumgebung in die Test- und Entwicklungsumgebung zurückspielen, um bestehende Testdaten gegen reale Informationen auszutauschen.

Anders als bei der Projektübertragung existiert das Zielprojekt somit schon und wird nicht neu erstellt. Dies bedeutet gleichzeitig, dass in den zugehörigen CaaS-Instanzen und Spryker-seitig ebenfalls bereits Inhalte existieren. Nach dem ContentTransport unterscheiden sich diese Inhalte von denen des FirstSpirit-Projekts.

Die Übertragung neuer Inhalte in den Preview CaaS und ihre Erzeugung in Spryker erfolgt automatisch bei jeder Speicherung. Bestehende Inhalte - wie in den beschriebenen Situationen - müssten für ihre Persistierung im Gegensatz dazu einzeln neu gespeichert werden. Das Referenzprojekt enthält aus diesem Grund den Auftrag Spryker Preview Deployment, der sowohl die Befüllung des Preview CaaS als auch die Spryker-seitige Aktulisierung der Vorschauinhalte steuert. Er ist im ServerManager im Bereich Projekt-Eigenschaften  Auftragsverwaltung angelegt und lässt sich ausschließlich von Projektadministratoren ausführen.

Der Auftrag setzt voraus, dass zuvor sowohl FirstSpirit- als auch Spryker-seitig alle Konfigurationsschritte vollständig abgeschlossen wurden.

Nach der Durchführung des Auftrags enthält der Preview CaaS die Vorschauinhalte des FirstSpirit-Projekts. Außerdem sind Spryker-seitig zusätzlich zu den standardmäßig existierenden statischen Seiten und Kategorieseiten alle im Projekt enthaltenen Inhalts- und Magazinseiten angelegt. Die Inhalte sind anschließend in der Vorschau für die Redakteure verfügbar.

Der Auftrag Spryker Preview Deployment lässt sich jederzeit ausführen. Bei Bedarf kann somit zu jedem beliebigen Zeitpunkt die Konsistenz der Vorschaudaten sichergestellt werden.

Soll zusätzlich zur Konsolidierung der Vorschauinhalte eine Übertragung in die Storefront erfolgen, müssen die Inhalte freigegeben und publiziert werden. Das Referenzprojekt stellt für die Freigabe einen Arbeitsablauf bereit, der außerdem die Publikation einzelner Seiten ermöglicht. Darüber hinaus besitzt es den Auftrag Spryker Deployment, der alle freigegebenen Inhalte des Projekts in den Online CaaS überträgt und ihren Import nach Spryker auslöst. Der Auftrag lässt sich von ChiefEditoren mithilfe der im ContentCreator verfügbaren Aktion Veröffentlichung starten.

5.2. Navigationspflege

Neben einer Hauptnavigation besitzt ein Shop im Allgemeinen beliebig viele weitere Navigationen. Die mit dem FirstSpirit Connect for Spryker Commerce OS-Modul realisierte Integration bietet die Möglichkeit, diese Navigationen mit FirstSpirit zu pflegen und um weitere Menüpunkte zu ergänzen. Dafür ist jedoch vorher die Durchführung der nachfolgenden Schritte erforderlich.

Die beschriebenen Schritte beziehen sich auf die Erweiterung einer existierenden Navigation. Besteht stattdessen der Wunsch, eine vorhandene Navigation vollständig in FirstSpirit zu verwalten, sind ihre Menüpunkte Spryker-seitig zu löschen.

Alternativ lässt sich auch eine neue Navigation in FirstSpirit pflegen. Sie muss dafür zuvor in Spryker erzeugt werden.

Ersetzung des ContentNavigationWidgets

Das in der Auslieferung enthaltene FirstSpiritPreviewContentNavigationWidget ersetzt das in Spryker bestehende ContentNavigationWidget. In Spryker muss daher eine entsprechende Ersetzung stattfindet, indem das ContentNavigationWidget gelöscht und stattdessen das FirstSpiritPreviewContentNavigationWidget hinzugefügt wird.

Ergänzung eines weiteren Menüpunkts

Die Darstellung der Navigation in der Vorschau erfordert die Erzeugung eines weiteren Menüpunkts. Er dient als Platzhalter und muss innerhalb des Twig-Templates, das die Menüpunkte der ersten Ebene darstellt, ergänzt werden:

Ergänzung eines weiteren Menüpunkts
[..]
<ul class="menu {{ menuClass }} grid grid--center grid--no-wrap">
   {% for node in data.nodes %}
      [..]
   {% endfor %}

   {% if isFsPreview() %}
      <li class="fs-navigation-extension"
         style="padding-left: 1rem; transform: translate(0,15% );">
      </li>
   {% endif %}
</ul>
[..]
Definition der Preview ID

Zusätzlich zu dem Platzhalter wird für den Vorschaufall eine Preview ID benötigt. Sie ist in dem Twig-Template, das die Ausgabe der einzelnen Menüpunkte steuert, zu definieren:

Definition der Preview ID
{% block attributes %}
   {% if isFsPreview() and data.node.previewId is defined and data.node.previewId is not empty %}
      data-preview-id="{{ data.node.previewId }}" style="min-height: unset;"
   {% endif %}
{% endblock %}

Unter Umständen ist nach den vorgenommenen Änderungen eine Leerung des Caches für die Twig-Templates sowie eine Neuerzeugung des Frontends notwendig.

Nach einer erfolgreichen Durchführung der beschriebenen Schritte wird die entsprechende Navigation im ContentCreator um einen Button erweitert, der die Ergänzung zusätzlicher Menüpunkte ermöglicht. Die Ergänzung weiterer Menüpunkte erfordert das Bearbeiten- und Löschen-Recht. Fehlen einem Benutzer diese Rechte, ist der Button ausgeblendet.

img navigation
Abbildung 29. Button zur Erweiterung der Navigation

Ein Klick auf den Button öffnet einen Bearbeitungsdialog, in dem ein Strukturordner als Ziel des neuen Menüpunkts auszuwählen ist. Besitzt der referenzierte Strukturordner weitere Unterordner, werden diese automatisch als Unterpunkte des neuen Menüpunkts dargestellt.

Die Mischung in FirstSpirit gepflegter und aus Spryker stammender Menüpunkte ist nicht möglich. Die über den ContentCreator erzeugten Menüpunkte werden aus diesem Grund ausschließlich an die bestehende Navigation angehängt.

Die an der Navigation vorgenommenen Änderungen erfordern abschließend eine Freigabe. Dafür lässt sich mithilfe eines Buttons, der beim Hovern über die Navigation erscheint, der Arbeitsablauf Freigabe der Navigation ausführen. Dieser Arbeitsablauf führt lediglich eine Freigabe, jedoch keine Publikation durch. Die Publikation der Anpassungen erfolgt erst im Rahmen einer Vollgenerierung.

Der Button zur Ausführung des Arbeitsablaufs setzt das Freigabe-Recht voraus. Fehlt einem Benutzer dieses Recht, hat das Hovern über die Navigation keinen Effekt.

5.3. Pflege von Seitenattributen

Anders als die Absätze besitzen die Inhaltsseiten keinen EasyEdit-Rahmen und damit auch nicht die mit ihm bereitgestellten Buttons. Für Inhaltsseiten steht im ContentCreator somit keine direkte Bearbeitungsmöglichkeit zur Verfügung. Das Aktionen-Menü beinhaltet daher den Menüpunkt Seite bearbeiten, der ausschließlich für Inhaltsseiten sichtbar ist. Er öffnet den Bearbeitungsdialog der Seite und ermöglicht die Pflege der Seitenattribute und Metadaten. Die Attribute sind sowohl für die Erzeugung der zugehörigen Seite in Spryker als auch für SEO-Konfiguration erforderlich.

actions editpage
Abbildung 30. Seite bearbeiten

5.4. Entfernung verwaister Produkt- und Kategorieseiten

Im Verlauf eines Projekts kann es jederzeit zu einer Spryker-seitigen Löschung bzw. Deaktivierung nicht mehr benötigter Produkte oder Kategorien kommen. Diese sind jedoch möglicherweise noch innerhalb des FirstSpirit-Projekts referenziert. Durch die Löschung bzw. Deaktivierung entstehen verwaiste Produkt- und Kategorieseiten, die während des Imports Fehler und Warnungen hervorrufen können. Diese verwaisten Seiten sind nicht mehr aufrufbar und somit durch Redakteure nicht identifizierbar.

Der ContentCreator stellt daher den Report Lost and Found zur Verfügung. Dieser zeigt eine Übersicht aller verwaisten Seiten innerhalb des FirstSpirit-Projekts an und ermöglicht eine Filterung nach Produkt- bzw. Kategorieseiten. Jeder Eintrag besitzt einen Lösch-Button, der beim Hovern über den Eintrag erscheint und nach der Bestätigung einer Sicherheitsabfrage einen Lösch-Arbeitsablauf anstößt. Der Arbeitsablauf entfernt die entsprechende Seite aus dem FirstSpirit-Projekt, gibt die übergeordnete Struktur frei und führt abschließend ein Voll-Deployment durch.

Die Ausführung des Lösch-Arbeitsablaufs erfordert sowohl das Lösch- als auch das Freigaberecht. Fehlt dem Redakteur eines dieser Rechte, ist der Lösch-Button für ihn ausgeblendet und die Entfernung verwaister Seiten somit nicht möglich.

img lostandfound
Abbildung 31. Report Lost and Found

6. Rechtliche Hinweise

FirstSpirit Connect for Spryker Commerce OS ist ein Produkt der Crownpeak Technology GmbH, Dortmund, Germany.
Für die Verwendung des Moduls gilt nur die mit der Crownpeak Technology GmbH vereinbarte Lizenz.

Details zu möglicherweise fremden, nicht von der Crownpeak Technology GmbH hergestellten, eingesetzten Software-Produkten, deren eigenen Lizenzen und gegebenenfalls Aktualisierungsinformationen, finden Sie in der Datei THIRD-PARTY.txt, die mit dem Modul ausgeliefert wird.

Alle im ausgelieferten Referenzprojekt FirstSpirit Connect for Spryker Commerce OS Reference Project enthaltenen Bilder stammen von dem Anbieter pixabay.

7. Hilfe

Der Technical Support der Crownpeak Technology GmbH bietet qualifizierte technische Unterstützung zu allen Themen, die FirstSpirit™ als Produkt betreffen. Weitere Hilfe zu vielen relevanten Themen erhalten und finden Sie in auch in unserer Community.