ContentConnect

For Spryker Commerce OS

e-Spirit AG

08.04.2021
Inhaltsverzeichnis

1. Einleitung

FirstSpirit dient der Erstellung vielseitiger und projektspezifischer Inhalte. Mit dem Modul ContentConnect 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 201907.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 ContentConnect for Spryker Commerce OS-Moduls ist das Referenzprojekt ContentConnect 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

ContentConnect 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 (vgl. Abbildung Architektur).

Diese Komponenten sind:

  • die auf dem FirstSpirit-Server installierten Module:

    • ContentConnect
    • Omnichannel Manager
    • Content as a Service
  • Spryker-Instanz
Architektur
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 ContentConnect-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 ContentConnect Reference Project werden die CMS Placeholder 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.

Page Rendering
Abbildung 2. Page Rendering


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

1.3.2. Vorschau

Die mit dem ContentConnect-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 Placeholder 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 ContentConnect-Moduls müssen die folgenden technischen Voraussetzungen erfüllt sein:

  • die Module ContentConnect, Content as a Service und Omnichannel Manager in der jeweils aktuellen Version
  • FirstSpirit (Legacy oder Isolated Modus) ab der Version 2019-05
  • Java 8 oder 11
  • Spryker Commerce OS

Bei der Verwendung des mitgelieferten Referenzprojekts ContentConnect 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 ContentConnect-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.

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.

Konfiguration der Einstellungsseite in den Projektoptionen
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 ContentConnect-Modul noch die Integration ist. Dennoch werden sie nachfolgend aufgelistet und eine mögliche Lösung skizziert.

Vagrant findet VirtualBox nicht

Ist es Vagrant nicht möglich, VirtualBox zu finden, ist der vagrant up-Befehl wie folgt zu erweitern:

Erweiterung des Befehls vagrant up. 

vagrant up --provider=virtualbox

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 FirstSpirit, 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',
   'FirstSpirit'
];

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 firstspirit/firstspirit-caas
composer require firstspirit/firstspirit-preview
composer require firstspirit/firstspirit-data-state-writer
composer require firstspirit/firstspirit-data-cleanup
composer require firstspirit/firstspirit-data-import
composer require firstspirit/firstspirit-data-inconsistency-check
composer require firstspirit/firstspirit-data-rest-api
composer require firstspirit/firstspirit-cms-data-connector
composer require firstspirit/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 ContentConnect-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 firstspirit/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/firstspirit'),
   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/firstspirit/**/*"
],

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 werden in der Beschreibung statischer Seiten erläutert. Die übrigen Twig-Templates sind ein Bestandteil der in der Auslieferung enthaltenen zip-Datei und unter den folgenden Pfaden abzulegen:

  • Kategorieseiten: src/Pyz/Yves/CmsBlockWidget/Theme/default/views/catalog-with-cms-block
  • Produktseiten: 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. 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_CAAS_TECHNICAL_PAGE_COLLECTION] = '<CAAS COLLECTION>';
$config[FirstSpiritPreviewConstants::FIRSTSPIRIT_PREVIEW_CAAS_NAVIGATION_DOCUMENT] = '<NAVIGATION DOCUMENT>';
$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>;

// ----------- 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>';

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 HeadersSecurityExtensionPlugins. 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.

Die Konfiguration der CaaS Collection für technische Seiten sowie des Dokuments für Navigationen sind für die Pflege und Erweiterung der im Shop enthaltenen Navigationen mit FirstSpirit erforderlich. Da beide Parameter einen Standardwert (technical bzw. navigations) besitzen, ist ihre Konfiguration optional und lediglich bei Abweichungen notwendig.

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 FirstSpirit\Shared\FirstSpiritPreview\FirstSpiritPreviewConstants;
use FirstSpirit\Shared\FirstSpiritDataImport\FirstSpiritDataImportConstants;
use FirstSpirit\Shared\FirstSpiritCaaS\FirstSpiritCaaSConstants;

2.1.4. 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 einige vorschauspezifische JavaScript- und CSS-Dateien voraus, die im FirstSpiritPreview-Modul enthalten sind.

Sowohl die JavaScript- als auch die CSS-Dateien sind 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 fsIncludeOcmFiles sowie über die Erweiterung der Template-Daten. Die Twig-Funktion fsIncludeOcmFiles erwartet für die Einbindung der JavaScript- bzw. CSS-Dateien einen entsprechenden Identifier.

Anpassung des Twig-Templates. 

{% block headStyles %}
   <link rel="stylesheet" href="{{publicPath('css/yves_default.app.css')}}" />
   {{ fsIncludeOcmFiles(identifier='css') }}
{% endblock %}

<body [..] {{ fsIncludeDataAttributes() }}>

   [..]

   {% block footerScripts %}
      <script src="{{publicPath('js/yves_default.es6-polyfill.js')}}"></script>
      <script src="{{publicPath('js/yves_default.vendor.js')}}"></script>
      <script src="{{publicPath('js/yves_default.app.js')}}"></script>
      {{ fsIncludeOcmFiles(identifier='js') }}
   {% endblock %}

</body>

2.2. Plugins

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

  • HeadersSecurityExtensionPlugin
  • FsTwigExtensionPlugin
  • FirstSpiritDataImportsResourceRoutePlugin
  • FirstSpiritDataCleanupsResourceRoutePlugin
  • FirstSpiritCmsPagesResourceRoutePlugin
  • UserAndCustomerOauthScopeProviderPlugin
HeadersSecurityExtensionPlugin und FsTwigExtensionPlugin

Das HeadersSecurityExtensionPlugin 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 ShopApplicationDependencyProvider im Verzeichnis src/Pyz/Yves/ShopApplication hinzuzufügen ist.

Erweiterung des ShopApplicationDependencyProviders. 

use FirstSpirit\Yves\FirstSpiritPreview\Plugin\HeadersSecurityExtensionPlugin;
use FirstSpirit\Yves\FirstSpiritPreview\Plugin\FsTwigExtensionPlugin;

[...]

protected function getApplicationPlugins(): array
{
   return [
      new HeadersSecurityExtensionPlugin(),
      new FsTwigExtensionPlugin()
   ];
}

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 FirstSpirit\Glue\FirstSpiritDataRestApi\Plugin\FirstSpiritDataImportsResourceRoutePlugin;
use FirstSpirit\Glue\FirstSpiritDataRestApi\Plugin\FirstSpiritDataCleanupsResourceRoutePlugin;
use FirstSpirit\Glue\FirstSpiritDataRestApi\Plugin\FirstSpiritCmsPagesResourceRoutePlugin;

[...]

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

UserAndCustomerOauthScopeProviderPlugin

Während der FirstSpirit-Generierung erfolgt eine Spryker-seitige Authentifizierung mit dem Customer, der während der FirstSpirit-seitig durchzuführenden Konfiguration in der Projekt-Komponente anzugeben ist. Das UserAndCustomerOauthScopeProviderPlugin prüft, ob dieser Customer einem Zed-User zugewiesen ist. Ist dies der Fall, fügt das Plugin dem von Spryker zurückgelieferten Authentifizierungstoken die für den Import notwendige Berechtigung zed-user hinzu.

Das Plugin erfordert eine Registrierung innerhalb des OauthDependencyProviders im Verzeichnis src/Pyz/Zed/Oauth. Dafür ist innerhalb der Methode getScopeProviderPlugins das CustomerOauthScopeProviderPlugin wie folgt zu ersetzen:

Registrierung des UserAndCustomerOauthScopeProviderPlugins. 

use FirstSpirit\Zed\FirstSpiritDataImport\Communication\Plugin\Oauth\UserAndCustomerOauthScopeProviderPlugin;

[...]

protected function getScopeProviderPlugins(): array
{
   return [
      new UserAndCustomerOauthScopeProviderPlugin()
   ];
}

2.3. 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.

  • FirstSpiritCategoryLinkWidget
  • FirstSpiritProductLinkWidget
  • FirstSpiritContentLinkWidget
  • FirstSpiritExternalLinkWidget
  • FirstSpiritProductFlyoutWidget
  • ExtendedNavigationWidget

Die ersten beiden Widgets 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.

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.

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.

Das ExtendedNavigationWidget schafft die Möglichkeit, die im Shop enthaltenen Navigationen mit FirstSpirit zu pflegen und um weitere Menüpunkte zu ergänzen. Es erweitert das bestehende NavigationWidget in Spryker und stellt verschiedene Attribute zur Verfügung, die für die Darstellung der entsprechenden Navigation in der Vorschau erforderlich sind.

Die Registrierung der Widgets erfolgt mithilfe des folgenden Codes, der dem ShopApplicationDependencyProvider im Verzeichnis src/Pyz/Yves/ShopApplication hinzuzufügen ist.

Erweiterung des ShopApplicationDependencyProviders. 

use FirstSpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritCategoryLinkWidget;
use FirstSpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritProductLinkWidget;
use FirstSpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritContentLinkWidget;
use FirstSpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritExternalLinkWidget;
use FirstSpirit\Yves\FirstSpiritPreview\Widget\FirstSpiritProductFlyoutWidget;
use Pyz\Yves\NavigationWidget\Widget\ExtendedNavigationWidget;

[...]

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

2.4. 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 FirstSpirit\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 anfangs genannten Controllern enthält die Auslieferung weitere RenderController, mit denen die Aktualisierung einzelner CMS-Elemente in der Vorschau möglich ist. Sie werden vom FirstSpiritPreviewControllerProvider angesprochen, der initial nicht in Spryker existiert und daher eine Registrierung in der YvesBootstrap-Datei im Verzeichnis Pyz/Yves/ShopApplication erfordert. Innerhalb der Datei ist die Methode getControllerProviderStack wie folgt zu erweitern.

Erweiterung der Methode getControllerProviderStack. 

use FirstSpirit\Yves\FirstSpiritPreview\Plugin\Provider\FirstSpiritPreviewControllerProvider;

[...]
protected function getControllerProviderStack($isSsl)
{
   return [
      [...]
      new FirstSpiritPreviewControllerProvider($isSsl)
   ];
}

2.5. Hauptnavigation

Der Spryker B2C Demo Shop enthält standardmäßig unterschiedliche Navigationen, die sich Spryker-seitig erzeugen und bearbeiten lassen. Die mit dem ContentConnect-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 sowohl in der Desktop- als auch in der mobilen Version umgesetzt. Ihre Verwendung setzt die Referenzierung des ExtendedNavigationWidgets, die Erzeugung eines Platzhalters sowie die Ergänzung einer Preview ID voraus.

Das ExtendedNavigationWidget erweitert das bestehende NavigationWidget und stellt verschiedene Attribute für die Vorschaudarstellung der Navigation bereit. Es muss daher anstelle des NavigationWidgets referenziert werden. Für die Desktopversion ist dafür die Anpassung der header.twig-Datei im Verzeichnis src/Pyz/Yves/ShopUi/Theme/default/components/organisms/header erforderlich:

Anpassung der header.twig-Datei. 

[..]
   {% widget 'ExtendedNavigationWidget' args ['MAIN_NAVIGATION_DESKTOP', 'navigation-header'] %}
   {% endwidget %}
[..]

Die Referenzierung des ExtendedNavigationWidgets für die mobile Hauptnavigation erfolgt in der side-drawer.twig-Datei im Verzeichnis src/Pyz/Yves/ShopUi/Theme/default/components/organisms/side-drawer:

Anpassung der side-drawer.twig-Datei. 

[..]
   {% widget 'ExtendedNavigationWidget' args ['MAIN_NAVIGATION', 'navigation-header-mobile'] %}
   {% endwidget %}
[..]

Die Darstellung der Navigation in der Vorschau erfordert die Erzeugung eines weiteren Menüpunkts, der als Platzhalter dient. Dieser ist für die Desktopversion in 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>
[..]

Die Ergänzung des Platzhalters in der mobilen Hauptnavigation erfolgt über eine Änderung der navigation-header-mobile.twig-Datei im Verzeichnis src/Pyz/Yves/NavigationWidget/Theme/default/components/molecules/navigation-header-mobile:

Anpassung der navigation-header-mobile.twig-Datei. 

[...]
{% block body %}
   [...]
   {% include molecule('toggler-accordion') with {
      attributes: {
         trigger: '.js-navigation-multilevel-node__trigger',
         'class-to-toggle': 'navigation-multilevel-node__menu--hidden',
         activeClass: 'navigation-multilevel-node__icon--active'
      }
   } only %}
   {% if isFsPreview() %}
      <li class="fs-navigation-extension"></li>
   {% endif %}
{% endblock %}
[...]

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. Da beide Versionen der Hauptnavigation auf diese Datei zugreifen, ist in diesem Schritt lediglich eine Anpassung notwendig:

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 %}

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

2.6. Error Page

Enthält eine Seite illegalen Code zeigt Spryker einen sogenannten Fail Whale an. Dabei handelt es sich um eine von Spryker standardmäßig bereitgestellte Fehlerseite. Da diese keine Navigationsmöglichkeiten besitzt, versetzt sie den Benutzer in einen Zustand, aus dem er keine andere Shopseite mehr aufrufen kann.

In der Auslieferung ist daher eine Fehlerseite enthalten, die sich dem Design der übrigen Shopseiten anpasst und sowohl einen Header als auch einen Footer einbindet. Für ihre Verwendung muss der Inhalt des Ordners ErrorPage in das bereits bestehende Verzeichnis src/Pyz/Yves/ErrorPage kopiert werden. Der Ordner ist ein Bestandteil der mitgelieferten zip-Datei b2c-demo-shop-extensions-<VERSION>.zip.

Des Weiteren ist der Seite error.html im Verzeichnis src/public/Yves/errorpage die folgende Zeile hinzuzufügen:

Erweitererung der error.html. 

<meta http-equiv="Refresh" content="0; url=/error/500" />

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 ContentConnect-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 ContentConnect-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 ControlUser ü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.

Der Import-Befehl muss 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 FirstSpirit\Zed\FirstSpiritDataImport\Communication\Console\FsDataImportConsole;

[...]

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

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

2.10. Frontend-Einstiegspunkt

Der FirstSpirit ContentCreator generiert und aktualisiert standardmäßig lediglich vollständige Seiten. Um innerhalb der Vorschau zusätzlich die Aktualisierung einzelner Absätze zu ermöglichen, wird Spryker-seitig ein weiterer EventListener benötigt. Dieser muss dem Frontend-Einstiegspunkt hinzugefügt werden. Dafür ist die app.ts-Datei im Verzeichnis src/Pyz/Yves/ShopUi/Theme/default wie folgt zu erweitern:

Erweiterung der Datei app.ts. 

import { bootstrap, mount } from 'ShopUi/app';
bootstrap();
document.addEventListener('NewComponentAttached', () => mount());

Existiert die app.ts-Datei unter dem genannten Pfad nicht, muss sie mit dem beschriebenen Inhalt angelegt werden.

2.11. 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, veschiedener 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 EventDependencyProviders im Verzeichnis Pyz/Zed/Event hinzuzufügen ist.

Erweiterung des EventDependencyProviders. 

use FirstSpirit\Zed\FirstSpiritCmsDataStorage\Communication\Plugin\Event\Subscriber\FirstSpiritCmsDataStorageEventSubscriber;

[...]

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

      [...]
      $eventSubscriberCollection->add(new FirstSpiritCmsDataStorageEventSubscriber());
      [...]

      return $eventSubscriberCollection;
   }
}

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

Erweiterung der RabbitMqConfig-Datei. 

use FirstSpirit\Shared\FirstSpiritCmsDataStorage\FirstSpiritCmsDataStorageConstants;

[...]

class RabbitMqConfig extends SprykerRabbitMqConfig
{
   protected function getQueueOptions()
   {
      $queueOptionCollection = new ArrayObject();

      [...]

      $queueOptionCollection->append($this->createQueueOption(
         FirstSpiritCmsDataStorageConstants::FS_CMS_BLOCK_DATA_SYNC_STORAGE_QUEUE,
         FirstSpiritCmsDataStorageConstants::FS_CMS_BLOCK_DATA_SYNC_STORAGE_ERROR_QUEUE,
         FirstSpiritCmsDataStorageConstants::FS_CMS_PAGE_DATA_SYNC_STORAGE_QUEUE,
         FirstSpiritCmsDataStorageConstants::FS_CMS_PAGE_DATA_SYNC_STORAGE_ERROR_QUEUE));

      [...]

      return $queueOptionCollection;
   }
}

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

Erweiterung des QueueDependencyProviders. 

use FirstSpirit\Shared\FirstSpiritCmsDataStorage\FirstSpiritCmsDataStorageConstants;

[...]

protected function getProcessorMessagePlugins(Container $container)
{
   return [
      [...]
      FirstSpiritCmsDataStorageConstants::FS_CMS_BLOCK_DATA_SYNC_STORAGE_QUEUE =>
         new SynchronizationStorageQueueMessageProcessorPlugin(),
      FirstSpiritCmsDataStorageConstants::FS_CMS_PAGE_DATA_SYNC_STORAGE_QUEUE =>
         new SynchronizationStorageQueueMessageProcessorPlugin(),
      [...]
   ];
}

3. FirstSpirit - Installation und Konfiguration

Für die Verwendung der Funktionalitäten des ContentConnect-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 ContentConnect-Moduls ist eine projektspezifische Konfiguration notwendig. Diese wird über die Projekt-Komponente vorgenommen, die dem mitgelieferten Referenzprojekt bereits hinzugefügt ist.

Zur Nutzung des ContentConnect-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-EigenschaftenProjekt-Komponenten.

Server-Eigenschaften - Projekt-Komponenten
Abbildung 4. Server-Eigenschaften - Projekt-Komponenten


Im Hauptpanel ist eine Liste aller bereits vorhandenen Projekt-Komponenten zu sehen. Selektieren Sie den Eintrag ContentConnect 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.

Projekt-Komponente - Allgemein
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 /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.

Projekt-Komponente - Vorschau
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.

Projekt-Komponente - Veröffentlichung
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.

Projekt-Komponente - 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-EigenschaftenWeb-Applikationen installiert. In diesem Fall sind alle für die Web-Komponente erforderlichen Installations- und Konfigurationsschritte bereits seitens der e-Spirit AG 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-EigenschaftenWeb-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 ContentConnect 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.

Web-Komponenten in den Projekt-Eigenschaften
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-EigenschaftenContentCreator 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.

Externe Vorschau-URL
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-EigenschaftenKonvertierungs-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 ContentConnect Reference Project jedoch bereits enthalten.

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

Ausgabekanal
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 ContentConnect 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-EigenschaftenAuflösungen angelegt und an den entsprechenden Stellen angegeben.

Auflösungen
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-EigenschaftenAuftragsverwaltung angelegt ist. Er lässt sich mithilfe der im ContentCreator verfügbaren Aktion Veröffentlichung starten und enthält die folgenden Aktionen:

Aktionen der Vollgenerierung
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.

Eigenschaften des Auftrags
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 e-Spirit AG 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.

Konfigurationsparameter
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 e-Spirit AG 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 e-Spirit AG bereitgestelltes CDN. Das Referenzprojekt besitzt dafür den Auftrag Media Deployment, der innerhalb des ServerManagers im Bereich Projekt-EigenschaftenAuftragsverwaltung 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.

Aktionen der Mediengenerierung
Abbildung 16. Aktionen der Mediengenerierung


Besteht der Wunsch, anstelle des bereitgestellten CDNs der e-Spirit AG 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 e-Spirit AG 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.

Eigenschaften der Aktion Media Generation
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 e-Spirit AG 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 e-Spirit AG bereitgestellt.

Publish to CDN
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-EigenschaftenAuftragsverwaltung 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.

Aktionen der Vorschaugenerierung
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.

Eigenschaften der Aktion 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 sowie von Menüpunkten in der Navigation 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 ContentConnect 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-EigenschaftenContentCreator innerhalb des ServerManagers. Im Referenzprojekt ContentConnect Reference Project ist diese Einstellung ebenfalls bereits vorgenommen.

Element Status Provider
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 ExtrasRechte ä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.

Erweiterung des Freigabe-Arbeitsablaufs
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 Referenzprojekt enthält eine technische Seitenreferenz, die der Erzeugung des JSONs aller im Projekt gepflegten Navigationen dient. Sie ist mithilfe der Eingabekomponente zu referenzieren, um die Übertragung des JSONs in den Preview CaaS sicherzustellen.

Projekteinstellungen - Allgemein
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.

Projekteinstellungen - Static Pages
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 ContentConnect-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 ContentConnect-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 ContentCreator 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 ContentConnect 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_VALUE(#global.page.body("stage"))$
   $CMS_VALUE(#global.page.body("homepage_one"))$
   $CMS_VALUE(#global.page.body("homepage_two"))$
   $CMS_VALUE(#global.page.body("homepage_three"))$
   $CMS_VALUE(#global.page.body("homepage_four"))$

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

   $CMS_VALUE(json.toJSON)$
$CMS_END_TRIM$

Die Seite bildet das Twig-Template home.twig ab und besitzt die Inhaltsbereiche stage sowie homepage_one|two|three|four. 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.

Im Gegensatz zu den übrigen Seiten besitzen statische Seite keine Placeholder, sondern nur einzelne Blöcke. Diese Blöcke werden in der Seitenvorlage homepage durch jeweils einen Inhaltsbereich repräsentiert. Jeder Inhaltsbereich darf seinerseits lediglich einen einzigen Absatz einbinden, der die redaktionellen Inhalte enthält.

Zur Vermeidung fehlerhafter Zustände ist die Verschiebung von Absätzen auf statischen Seiten im ContentCreator aus diesem Grund unterbunden.

Zusätzlich zu den redaktionellen Inhalten werden dem JSON-Objekt die previewId, der Identifier und der Page Type ü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 stage sowie homepage_one|two|three|four. Der Inhaltsbereich stage stellt lediglich ein Karussell bereit, das ein oder mehrere Banner einbindet. Im Gegensatz dazu ermöglichen die übrigen Inhaltsbereiche 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 wird.

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 des Absatzes 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 des Absatzes sowohl im Vorschaufall als auch im Live-Stand zu gewährleisten, müssen der Name und der Pfad dieses Twig-Templates im CaaS-Item gespeichert sein.

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. Generell sind die Inhaltsbereiche einer Seitenvorlage äquivalent zu den CMS Placeholdern in Spryker. Eine statische Seite enthält jedoch keine Placeholder. Aus diesem Grund muss der Blockname an dieser Stelle dem Namen des zugehörigen Inhaltsbereichs entsprechen.

Mithilfe der Formatvorlage additional_block_attributes_render werden dem Block bei Bedarf weitere Attribute hinzugefügt.

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 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.

Bearbeitungsdialog für Video-Items
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, müssen die bestehenden CMS Blöcke ersetzt werden. Für die Einbindung eines Blocks ist die Verwendung der Twig-Funktion fsSpyCmsBlock notwendig.

Im Fall statischer Seiten repräsentiert jeder Block einen Inhaltsbereich der entsprechenden FirstSpirit-Seitenvorlage. Aus diesem Grund müssen der Name des CMS Blocks und der Name des jeweiligen Inhaltsbereichs identisch sein. Jedem dieser Inhaltsbereiche kann nur genau ein Absatz hinzugefügt werden, für den Spryker-seitig ein Block Twig-Template existieren muss.

Die im Referenzprojekt enthaltene Seitenvorlage homepage stellt ein Beispiel für eine statische Seite dar. Sie bildet das Twig-Template home.twig ab und besitzt die Inhaltsbereiche stage sowie homepage_oneone|two|three|four. Das folgende Code-Beispiel zeigt die Einbindung der gleichnamigen Blocks innerhalb des Twig-Templates, um die statische Seite im ContentCreator bearbeitbar zu machen.

Erweiterung des Twig-Templates home.twig. 

{% extends template('page-layout-main') %}

{% block header %}
   [...]
{% endblock %}

{% block pageInfo %}{% endblock %}

{% block container %}
   {{ fsSpyCmsBlock({ name: 'stage' }) }}
   <div class="container container--home-page">
      <main>
         {% block content %}
            {{ fsSpyCmsBlock({ name: 'homepage_one' }) }}
            {{ fsSpyCmsBlock({ name: 'homepage_two' }) }}
            {{ fsSpyCmsBlock({ name: 'homepage_three' }) }}
            {{ fsSpyCmsBlock({ name: 'homepage_four' }) }}

         {% endblock %}
      </main>
   </div>
{% endblock %}

Der in der Seitenvorlage homepage enthaltene Inhaltsbereich stage stellt lediglich ein Karussell bereit, das ein oder mehrere Banner einbindet. Im Gegensatz dazu ermöglichen die übrigen Inhaltsbereiche 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.

Darstellung des Absatzes
Abbildung 26. Darstellung des Absatzes


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-seitige 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.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 page-layout-catalog.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, die beide nur auf Seiten für Unterkategorien verwendbar sind, steht auf allen 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 einer Überschrift und eines Untertitels. Sowohl für die Überschrift als auch für den Untertitel ist eine Textfarbe selektierbar. Das Banner entspricht dem Spryker-seitigen Molekül fs-banner.twig, dessen Ausgabe ebenfalls das generische Twig-Template fs_molecule_block.twig steuert.

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

Das Twig-Template catalog-with-cms-block.twig stellt Spryker-seitig einen Kategorie-Absatz dar. Es 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 dieser Templates über die Twig-Funktion fsSpyCmsBlock erfolgen.

Jeder CMS Block entspricht einem FirstSpirit-Absatz, der an einer bestimmten Position in der Kategorieseite platziert ist. Die Verwendung von Positionen in Kategorieseiten wird Spryker-seitig durch das Feature CMS Block Category Connector ermöglicht, 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. 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.

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 page-layout-catalog.twig ab. Dieses wird durch das Twig-Template catalog-with-cms-block.twig erweitert, das ein Bestandteil der in der Auslieferung enthaltenen zip-Datei b2c-demo-shop-extensions-<VERSION>.zip ist. Das Twig-Template catalog-with-cms-block.twig ermöglicht die Einbindung der in den Inhaltsbereichen top und bottom enthaltenen Absätze auf Seiten für Unterkategorien.

Während die CMS Blöcke top und bottom spezifisch für diese Unterkategorieseiten sind, steht der CMS Block banner auf allen Kategorieseiten zur Verfügung. Aus diesem Grund ist er 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. Für die Ergänzung des Banners muss der bereits bestehende Abschnitt block title innerhalb des Templates durch den folgenden Code ersetzt werden.

Einbindung des Banners. 

{% block title %}
   {{ fsSpyCmsBlock({category:data.category.id_category, position: 'banner'}) }}
{% endblock %}

Das Banner entspricht Spryker-seitig dem Molekül fs-banner, dessen Ausgabe das generische Twig-Template fs_molecule_block.twig steuert. Der folgende Code-Ausschnitt zeigt den Inhalt des Moleküls:

Molekül fs-banner. 

{% extends model('component') %}

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

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

{% block body %}
   <figure class="fs-banner"{% if data.fsBlockData.variant is not empty %} data-variant="{{data.fsBlockData.variant}}"{% 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 %}>

      {% if (data.fsBlockData.title is not empty) or (data.fsBlockData.subtitle is not empty) %}
         <figcaption>
            <hgroup>
               {% if data.fsBlockData.title is not empty %}
                  <h2>{{ data.fsBlockData.title | raw}}</h2>
               {% endif %}
               {% if data.fsBlockData.subtitle is not empty %}
                  <h3>{{ data.fsBlockData.subtitle | raw}}</h3>
               {% endif %}
            </hgroup>
         </figcaption>
      {% endif %}
   </figure>
{% endblock %}

Ebenso wie beim Molekül des Shoppable Video-Absatzes wird innerhalb des Templates 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-Absatzvorlage definiert sind. Das fsBlockData-Objekt und das FirstSpirit-seitig erstellte JSON-Objekt besitzen somit dieselbe Struktur.

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

Die folgende Abbildung zeigt die Darstellung eines Karussells mit nur einem Element im ContentCreator.

Karussell mit einem Element
Abbildung 27. Karussell mit einem Element


Das folgende Code-Beispiel entspricht dem Twig-Template catalog-with-cms-block.twig inklusive der für die FirstSpirit-seitige Bearbeitung notwendigen Anpassungen. Es ermöglicht die Einbindung der übrigen Absätze, die nicht dem Karussell entsprechen, auf Seiten für Unterkategorien. 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-block.twig. 

{% extends template('widget') %}

{% block top %}
   {{ fsSpyCmsBlock({category: _widget.idCategory, position: 'top'}) }}
{% endblock %}

{% block middle %}
   {{ spyCmsBlock({category: _widget.idCategory, position: 'middle'}) }}
{% endblock %}

{% block bottom %}
   {{ fsSpyCmsBlock({category: _widget.idCategory, position: 'bottom'}) }}
{% endblock %}

{% block body %}
   {{ spyCmsBlock({category: _widget.idCategory, position: _widget.position}) }}
{% endblock %}

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. Es erweitert das übergeordnete Template pdp.twig, in dem das Basis-Layout aller Produktseiten definiert ist.

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 ContentConnect-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 wird 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 ContentConnect-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)$

$-- 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 - sowohl in der Desktop- als auch in der mobilen Version - 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:

  • header.twig
  • side-drawer.twig
  • navigation-header.twig
  • navigation-header-mobile.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.

Button zur Erweiterung der 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 in der Desktop- und in der mobilen Version.

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.

  • header.twig
  • side-drawer.twig
  • navigation-header.twig
  • navigation-header-mobile.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 in der Desktop- und in der mobilen Version ab. Sie referenzieren die einzelnen Menüpunkte und steuern ihre Darstellung in der Vorschau und im Live-Stand. Mithilfe der Anpassungen erhalten beide Versionen der 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.

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-EigenschaftenAuftragsverwaltung 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 ContentConnect-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 NavigationWidgets

Das in der Auslieferung enthaltene ExtendedNavigationWidget erweitert das in Spryker bestehende NavigationWidget. Es muss daher in der Datei, die der Referenzierung der entsprechenden Navigation dient, anstelle des NavigationWidgets eingebunden werden:

Ersetzung des NavigationWidgets. 

[..]
   {% widget 'ExtendedNavigationWidget' args ['NAVIGATION_NAME', 'navigation-header'] %}
   {% endwidget %}
[..]

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.

Button zur Erweiterung der 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.

Seite bearbeiten
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.

Report Lost and Found
Abbildung 31. Report Lost and Found


6. Rechtliche Hinweise

ContentConnect ist ein Produkt der e-Spirit AG, Dortmund, Germany.
Für die Verwendung des Moduls gilt nur die mit der e-Spirit AG vereinbarte Lizenz.

Details zu möglicherweise fremden, nicht von der e-Spirit AG 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 ContentConnect Reference Project enthaltenen Bilder stammen von dem Anbieter pixabay.