Erweiterung des Blog Plugins in Shopware 6

Wer regelmäßig mit Shopware 6 arbeitet, wird nicht lange brauchen, bis er oder sie die Custom Fields lieben lernt. Eine einfache und unkomplizierte Möglichkeit Shopware um zusätzliche Optionen zu erweitern, die den eigenen Online-Shop zu etwas ganz besonderem machen. Doch während die Erweiterung von Produkten oder Kategorien mit wenigen Klicks funktioniert, kann es bei anderen Entitäten oft ein kleines bisschen komplizierter werden.
In unserem konkreten Fall sehen wir uns folgendes Beispiel an: Wir möchten das Shopware Blog Plugin, um ein Feld erweitern, das angibt, ob es sich bei dem jeweiligen Beitrag um einen "Highlight"-Blogbeitrag handelt. Am Schluss möchten wir alle Highlight-Blogbeiträge in einem eigenen Custom Content Element anzeigen.
In diesem Beitrag sehen wir uns folgende Inhalte etwas genauer an:
- Eine kurze Einführung in Custom Fields
- Hinzufügen von Custom Fields durch Aktivieren eines Plugins
- Erweitern der Adminview
- Ausgabe der Inhalte im Frontend auf Basis der Werte der Custom Fields
Was sind Custom Fields?
Shopware selbst erklärt das in der Doku wie folgt:
Shopware's custom field system allows you to extend entities, without writing a complete entity extension. This is possible by storing the additional data in a JSON-Field.
Diese Felder lassen sich sogar im Backend über Einstellungen -> System -> Zusatzfelder mit nur wenigen Klicks hinzufügen. Durch die Auswahl einzelnen Entitäten werden die zuvor konfigurierten Felder anschließend auf der Detailansicht der jeweilig ausgewählten Entität angezeigt. Allerdings hat das ganze einen Hacken: Unter "Verwenden für" werden nur die Shopware Core Entitäten – wie zum Beispiel Produkte, Kategorien, Hersteller, Kunden, Bestellungen, etc. – angezeigt.
Für das Hinzufügen für unsere "Highlight"-Checkbox bei den Blogbeiträgen müssen wir somit eine andere Option finden. Und zwar das...
Hinzufügen der Custom Fields durch Aktivieren eines Plugins
Ja, auch das ist in Shopware möglich und wir schauen uns jetzt an wie! Zu allererst müssen wir überprüfen, ob die Entität die wir um Custom Fields erweitern möchten, sich auch dadurch erweitern lässt. Dazu ist ein kurzer Blick in die Datenbank notwendig. In unserem Fall heißt die gesuchte Datenbank-Tabelle sas_blog_entries und in der dazugehörigen Translationstabelle sas_blog_entries_translations finden wir eine Spalte namen custom_fields, die überall den Wert null haben sollte.
Alles klar soweit? Dann sehen wir uns jetzt an wie wir die Spalte custom_fields tatsächlich mit Werten füllen können!
Dazu müssen wir uns das unser eigenes Plugin suchen, dass für das Hinzufügen der Felder verantwortlich sein soll. In unserem Fall sind die Erweiterungen für das Blog Plugin in einem eigenen Plugin SmdmBlogExt gekapselt. Es ist natürlich auch in Ordnung dafür das eigene Theme zu verwenden.
Das Hinzufügen ist somit in unserem Fall in SmdmBlogExt/src/SmdmBlogExt.php durchzuführen, dort kannst du folgenden Code ganz ungeniert reinkopieren ;-)
public function activate($context): void
{
/** @var EntityRepositoryInterface $cmsBlockRepo */
$this->setupCustomFields($context);
}
public function setupCustomFields($context): void
{
$customFieldSetRepository = $this->container->get('custom_field_set.repository');
$customFieldSets = [
[
'name' => 'custom_blog_fields',
'config' => [
'label' => [
'en-GB' => 'Extension Blog Articles',
'de-DE' => 'Erweiterung Blog Artikel',
]
],
'customFields' => [
[
'name' => 'isHighlight',
'type' => CustomFieldTypes::SWITCH,
'config' => [
'label' => [
'en-GB' => 'Show article in hightlights',
'de-DE' => 'Zeige Artikel in Highlights',
],
'customFieldPosition' => 1
]
],
[
'name' => 'showInHeader',
'type' => CustomFieldTypes::SWITCH,
'config' => [
'label' => [
'en-GB' => 'Show article in homepage header',
'de-DE' => 'Zeige Artikel im Homepage-Header',
],
'customFieldPosition' => 2
]
],
[
'name' => 'subtitle',
'type' => CustomFieldTypes::TEXT,
'config' => [
'label' => [
'en-GB' => 'Subtitle',
'de-DE' => 'Untertitel',
],
'customFieldPosition' => 3
]
]
],
'relations' => [
[
'entityName' => 'sas_blog_entries',
]
]
],
];
$customFieldSetRepository->upsert($customFieldSets, $context->getContext());
}
Nähere Informationen zur Konfiguration von Custom Fields findest du in der Shopware Doku. Wenn wir unser Plugin dann über das Backend oder die Console deaktivieren und erneut aktivieren, werden die Custom Fields automatisch hinzugefügt. Überprüfen kannst du das wieder in dem du unter Einstellungen -> System -> Zusatzfelder nachsiehst, ob dein Fieldset hier aufscheint. Aber Achtung: Unter "Verwenden für" ist diese Entität nicht sichtbar, denn aus diesem Grund haben wir die Custom Fields über diesen Umweg hinzugefügt.
Auch das Anzeigen der Custom Fields in der Adminview ist leider bei zusätzlich hinzugefügten Entitäten etwas mehr Aufwand als sonst, aber auch das schaffen wir gemeinsam.
Erweitern der Adminview
Während bei Shopware Core Entitäten die Custom Fields automatisch ganz unten auf der Detailseite unter "Zusatzfelder" gerendert werden, ist das bei nicht Core-Entitäten etwas anders. Auf der einen Seite ist es zwar initial mehr Aufwand die Felder hinzuzufügen, auf der anderen Seite haben wir somit mehr Freiraum und können die Felder genau dort positionieren, wo wir sie haben wollen und sind somit sogar flexibler.
Um die Detail-Seite eines Blogbeitrags in der Adminview zu überschreiben, brauchen wir zwei Files:
- Ein File, dass festlegt, welches Admin-Template überschrieben bzw. erweitert werden soll:
SmdmBlogExt/src/Resources/app/administration/src/module/blog_module/page/sas-blog-detail/index.js - Das Twig-File, dass die zu überschreibende View erweitert:
SmdmBlogExt/src/Resources/app/administration/src/module/blog_module/page/sas-blog-detail/sas-blog-detail.html.twig
Das index.js muss zusätzlich in unserem main.js sowie auch die Custom Content Elements importiert werden und schaut in unserem Beispiel folgendermaßen aus:
import template from './sas-blog-detail.html.twig';
Shopware.Component.override('sas-blog-detail', {
template,
methods: {
changeIsHighlight(value) {
this.blog.customFields = this.blog.customFields ? this.blog.customFields : {};
this.blog.customFields.isHighlight = value;
}
}
});
Das Erweitern der Admin-View mittels Twig-File funktioniert genauso wie auch im Frontend. Hier ergänzen wir das Template um ein Switch-Field:
{% block sas_blog_detail_field_detail_teaser %}
{% parent() %}
<sw-switch-field
style="margin-top: 0; margin-bottom: 0"
type="switch"
label="Zeige Artikel in Hightlights"
@change="changeIsHighlight($event)"
:value="blog.customFields?.isHighlight ? blog.customFields?.isHighlight : false"
></sw-switch-field>
{% endblock %}
Nun fehlt nur noch eine Klitze-Kleinigkeit:
Die Ausgabe im Frontend
Um unsere Blog-Highlights entsprechend darstellen zu können, basteln wir uns ein eigenes Custom CMS Element "Blog Highlights" (wie das funktioniert schauen wir uns ein anderes Mal an, bis dahin viel Freude mit der Shopware Doku dazu).
Am allerwichtigsten ist für unseren Fall, dass wir einen entsprechenden DataResolver brauchen, den wir im service.xml unseres Plugins registrieren. Unser BlogHighlightsCmsElementResolver könnte dann je nach Anforderung an das CMS Element wie folgt aussehen:
<?php declare(strict_types=1);
namespace SmdmBlogExt\DataResolver;
...
class BlogHighlightsCmsElementResolver extends BlogCmsElementResolver
{
public function getType(): string
{
return 'blog-highlights';
}
public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
{
/* get the config from the element */
$config = $slot->getFieldConfig();
$dateTime = new \DateTime();
$criteria = new Criteria();
$criteria->addAssociations([
'author',
'author.media',
'author.blogs',
'blogCategories',
'customFields'
]);
$criteria->addFilter(
new EqualsFilter('active', true),
new RangeFilter('publishedAt', [RangeFilter::LTE => $dateTime->format(\DATE_ATOM)]),
new EqualsFilter('customFields.isHighlight', 'true'),
);
$criteria->addSorting(
new FieldSorting('publishedAt', FieldSorting::DESCENDING)
);
if ($config->has('showType') && $config->get('showType')->getValue() === 'select') {
$blogCategories = $config->get('blogCategories') ? $config->get('blogCategories')->getValue() : [];
$criteria->addFilter(new EqualsAnyFilter('blogCategories.id', $blogCategories));
}
$criteriaCollection = new CriteriaCollection();
$criteriaCollection->add(
'sas_blog',
BlogEntriesDefinition::class,
$criteria
);
return $criteriaCollection;
}
}
Wenn wir den DataResolver richtig registriert haben, dann bekommen wir in unserem Blog-Highlights CMS Element nun die richtigen Daten zurück und können unsere Blog-Highlights nun noch etwas aufhübschen.
Fazit
Alles lässt sich erweitern, man muss nur wissen wie!