Live Demo: Teste dieses und weitere Plugins live — ohne Installation, ohne Risiko: demo.markus-michalski.net
| Schritt | Klasse | Verhalten |
|---|---|---|
| Filter | Mmd\ProductSnippets\Twig\SnippetExtension |
Filter mmd_snippets und Funktion mmd_snippet. Holt den Kontext aus der aktuellen Anfrage. Ohne Anfrage wird der Text unverändert zurückgegeben. |
| Ersetzen | Mmd\ProductSnippets\Core\Content\Snippet\SnippetReplacer |
Sammelt die Identifier, lädt die Bausteine, ersetzt per Regex und bereinigt jeden Inhalt mit dem HtmlSanitizer. Platzhalter ohne Treffer (unbekannt, inaktiv oder ohne Inhalt in der aktuellen Sprache) bleiben stehen. |
| Parsen | Mmd\ProductSnippets\Core\Content\Snippet\SnippetParser |
Regex {{ snippet:<identifier> }} bzw. {{ textbaustein:<identifier> }}, Identifier aus a-z, A-Z, 0-9, - und _, ohne Beachtung der Groß-/Kleinschreibung. |
| Laden | Mmd\ProductSnippets\Core\Content\Snippet\SnippetRegistry |
Cache-Schicht vor dem Repository mmd_product_snippet. |
cache.object. Der Schlüssel enthält Identifier und Sprach-ID, jede Sprache hat also einen eigenen Eintrag.Ein Subscriber (Mmd\ProductSnippets\Subscriber\CacheInvalidationSubscriber) hört auf die Entity-Events mmd_product_snippet.written und mmd_product_snippet.deleted:
active, es gibt keine Invalidierung. Ein deaktivierter Baustein bleibt deshalb weiter sichtbar, ein neu aktivierter bleibt als "nicht gefunden" im Cache.In den letzten beiden Fällen erscheint die Änderung spätestens nach Ablauf der 3600 Sekunden oder sofort nach bin/console cache:clear. Das Plugin invalidiert außerdem nicht den HTTP-Cache der Produktseiten.
| Tabelle | Inhalt |
|---|---|
mmd_product_snippet |
id, identifier (VARCHAR 255, UNIQUE, Collation utf8mb4_unicode_ci), active (Standard 1), Zeitstempel |
mmd_product_snippet_translation |
mmd_product_snippet_id, language_id, name, content (LONGTEXT), Zeitstempel. Löschen des Bausteins löscht kaskadierend die Übersetzungen. |
Die Entity heißt mmd_product_snippet (Felder identifier, active, name, content). Alle Felder sind für die Admin-API freigegeben, sodass sich Bausteine auch darüber lesen und schreiben lassen. Eine Validierung des Identifiers gibt es dort ebenfalls nicht.
src/
├── MmdProductSnippets.php # Plugin-Klasse, löscht Tabellen bei Deinstallation
├── Content/Snippet/ # Entity-Definitionen (Baustein und Übersetzung)
├── Core/Content/Snippet/ # Parser, Replacer, Registry
├── Migration/ # Legt die beiden Tabellen an
├── Subscriber/ # CacheInvalidationSubscriber
├── Twig/ # SnippetExtension (Filter, Funktion)
└── Resources/
├── app/administration/ # Admin-Modul (Liste und Detailseite)
├── config/services.xml
└── views/storefront/ # Drei Template-Overrides, unter Shopware 6.7 sind zwei wirksam
Von den drei Template-Overrides ist storefront/page/product-detail/description.html.twig unter Shopware 6.7 inaktiv, weil der Kern dieses Template nicht mehr bereitstellt. Details stehen auf der Seite Storefront-Integration.
Die Linie mmd/sw66-product-snippets (Shopware ~6.5.0 || ~6.6.0) hat denselben Funktionsumfang und im Wesentlichen denselben Quelltext. Beim Vergleich beider Linien unterscheiden sich vor allem diese Punkte:
| Bereich | Linie 6.7 | Linie 6.5 / 6.6 |
|---|---|---|
| Composer-Paket und Shopware-Anforderung | mmd/sw67-product-snippets, ~6.7.0 |
mmd/sw66-product-snippets, ~6.5.0 \|\| ~6.6.0 |
Inhalt auslesen (SnippetRegistry) |
Direkter Zugriff auf das Feld content der Entity (nur die aktuelle Sprache) |
getTranslation('content') (liest das Array translated, das die Fallback-Kette der Sprachen einbezieht) |
| Admin-Seiten (Liste und Detail) | Seitentitel über head(), Mixins über Shopware.Mixin.getByName() |
Seitentitel über metaInfo(), Mixins aus dem destrukturierten Mixin |
| Mitgeliefertes Admin-Bundle | Vite-Build unter Resources/public/administration/assets |
Dateien unter Resources/public/administration/js und .../css |
| Klassen der Entity-Schicht | final, Eigenschaften identifier und mmdProductSnippetId mit typisiertem Standardwert '' |
nicht final, Eigenschaften ohne Standardwert |
Kommentar im Template box-standard.html.twig |
Anmerkung zu \|raw |
ohne diese Anmerkung (nur Kommentar, kein Verhalten) |
Der Unterschied beim Auslesen wirkt sich auf das Verhalten aus: Fehlt der Inhalt in der aktuellen Sprache, kann die Linie 6.5/6.6 auf die Standardsprache zurückfallen, während in der Linie 6.7 der Platzhalter unersetzt stehen bleibt. Dass
getTranslation()die Fallback-Kette berücksichtigt, ist Verhalten des Shopware-Kerns und lässt sich im Quelltext des Plugins nicht belegen.
Dienstdefinitionen (services.xml), Migration, Tabellen, Platzhalter-Syntax, Twig-Filter und -Funktion, die Template-Dateien und die Admin-Texte stimmen in beiden Linien überein.