feat(cms): add subcategory columns CMS block with own "WSC AI-SEO" category #20

Merged
csaeum merged 1 commit from feature/cms-block-subcategory-columns into main 2026-08-08 23:25:07 +00:00
Owner

Zusammenfassung

Neuer CMS-Block für den Layout-Designer (Issue #19): Redakteur wählt eine Kategorie, deren direkte aktive Unterkategorien werden als Spalten mit Link gerendert. Spaltenbreite ist über ein Textfeld mit Bootstrap-Grid-Klassen konfigurierbar (Beispiel: col-6 col-md-4). Der Block erscheint im Block-Picker unter einer eigenen neuen Kategorie „WSC AI-SEO".

Umsetzung

  • src/Cms/SubcategoryColumnsCmsElementResolver.php + Struct/SubcategoryColumnsStruct.php: PHP-Resolver, lädt direkte, aktive Unterkategorien
  • src/Resources/app/administration/...: neues Administration-Verzeichnis (gab es in diesem Plugin bisher nicht) — CMS-Element + Block-Vue-Komponenten, Konfigurationspanel (Kategorie-Auswahl + Spaltenbreite-Textfeld), eigene Block-Kategorie „WSC AI-SEO"
  • src/Resources/views/storefront/...: Block- und Element-Twig-Templates
  • tests/Unit/Cms/SubcategoryColumnsCmsElementResolverTest.php: 5 neue Unit-Tests

Wichtiger Fund während der Verifikation

Der erste Ansatz nutzte Shopwares generischen CriteriaCollection-Mechanismus (CmsSlotsDataResolver) analog zu Shopwares eigenen CMS-Elementen. Live-Test in DDEV zeigte dann leere href-Attribute bei den gerenderten Links. Ursache: CmsSlotsDataResolver hat nur für die Entity product eine Sales-Channel-Repository-Zuordnung hinterlegt (Shopware\Core\Content\DependencyInjection\cms.xml), nicht für category. Dadurch griff beim generischen Weg das NICHT Sales-Channel-fähige category.repository, welches das Event sales_channel.category.loaded nie feuert — genau dieses Event befüllt category.seoUrl. Fix: Der Resolver lädt jetzt direkt über das injizierte sales_channel.category.repository in enrich(), collect() gibt bewusst null zurück. Danach lieferte der Live-Test korrekte, funktionierende Links.

Verifikation (DDEV sw6-plugin, real durchgespielt)

  • Admin-Build (bin/build-administration.sh) erfolgreich, Plugin-JS fehlerfrei gebündelt
  • Testkategorie mit 3 aktiven Unterkategorien temporär als Layout zugewiesen (über einen Wegwerf-Console-Command, danach vollständig zurückgesetzt und gelöscht — nicht Teil dieses Commits)
  • Storefront-Ausgabe geprüft: Block- und Spalten-CSS-Klassen korrekt, konfigurierte Bootstrap-Spaltenklassen korrekt übernommen, Kategorienamen übersetzt korrekt, SEO-Links funktionsfähig
  • Nach Verifikation: Original-Layout der Testkategorie wiederhergestellt, Test-Command entfernt, Shop-Health-Check (Start- und Kategorieseite) grün
  • Unit-Tests: 5 neue + 41 bestehende, alle grün

Bekannte Einschränkung

Kein Browser-Zugriff in dieser Session verfügbar — die Admin-UI (Block-Picker, „WSC AI-SEO"-Tab, Konfigurationsformular) wurde nicht visuell prüft, nur Build-Erfolg und die tatsächliche Storefront-Ausgabe. Ein kurzer manueller Blick ins Admin-Backend wird empfohlen.

Closes #19

## Zusammenfassung Neuer CMS-Block für den Layout-Designer (Issue #19): Redakteur wählt eine Kategorie, deren direkte aktive Unterkategorien werden als Spalten mit Link gerendert. Spaltenbreite ist über ein Textfeld mit Bootstrap-Grid-Klassen konfigurierbar (Beispiel: `col-6 col-md-4`). Der Block erscheint im Block-Picker unter einer eigenen neuen Kategorie **„WSC AI-SEO"**. ## Umsetzung - `src/Cms/SubcategoryColumnsCmsElementResolver.php` + `Struct/SubcategoryColumnsStruct.php`: PHP-Resolver, lädt direkte, aktive Unterkategorien - `src/Resources/app/administration/...`: neues Administration-Verzeichnis (gab es in diesem Plugin bisher nicht) — CMS-Element + Block-Vue-Komponenten, Konfigurationspanel (Kategorie-Auswahl + Spaltenbreite-Textfeld), eigene Block-Kategorie „WSC AI-SEO" - `src/Resources/views/storefront/...`: Block- und Element-Twig-Templates - `tests/Unit/Cms/SubcategoryColumnsCmsElementResolverTest.php`: 5 neue Unit-Tests ## Wichtiger Fund während der Verifikation Der erste Ansatz nutzte Shopwares generischen `CriteriaCollection`-Mechanismus (`CmsSlotsDataResolver`) analog zu Shopwares eigenen CMS-Elementen. Live-Test in DDEV zeigte dann leere `href`-Attribute bei den gerenderten Links. Ursache: `CmsSlotsDataResolver` hat nur für die Entity `product` eine Sales-Channel-Repository-Zuordnung hinterlegt (`Shopware\Core\Content\DependencyInjection\cms.xml`), nicht für `category`. Dadurch griff beim generischen Weg das NICHT Sales-Channel-fähige `category.repository`, welches das Event `sales_channel.category.loaded` nie feuert — genau dieses Event befüllt `category.seoUrl`. Fix: Der Resolver lädt jetzt direkt über das injizierte `sales_channel.category.repository` in `enrich()`, `collect()` gibt bewusst `null` zurück. Danach lieferte der Live-Test korrekte, funktionierende Links. ## Verifikation (DDEV `sw6-plugin`, real durchgespielt) - Admin-Build (`bin/build-administration.sh`) erfolgreich, Plugin-JS fehlerfrei gebündelt - Testkategorie mit 3 aktiven Unterkategorien temporär als Layout zugewiesen (über einen Wegwerf-Console-Command, danach vollständig zurückgesetzt und gelöscht — nicht Teil dieses Commits) - Storefront-Ausgabe geprüft: Block- und Spalten-CSS-Klassen korrekt, konfigurierte Bootstrap-Spaltenklassen korrekt übernommen, Kategorienamen übersetzt korrekt, SEO-Links funktionsfähig - Nach Verifikation: Original-Layout der Testkategorie wiederhergestellt, Test-Command entfernt, Shop-Health-Check (Start- und Kategorieseite) grün - Unit-Tests: 5 neue + 41 bestehende, alle grün ## Bekannte Einschränkung Kein Browser-Zugriff in dieser Session verfügbar — die Admin-UI (Block-Picker, „WSC AI-SEO"-Tab, Konfigurationsformular) wurde nicht visuell prüft, nur Build-Erfolg und die tatsächliche Storefront-Ausgabe. Ein kurzer manueller Blick ins Admin-Backend wird empfohlen. Closes #19
New CMS block for the layout designer: lets editors pick a category and
renders its direct active subcategories as columns, with a configurable
Bootstrap column-width field (e.g. "col-6 col-md-4"). Ships as its own
block category "WSC AI-SEO" in the block picker.

The resolver loads categories directly via sales_channel.category.repository
instead of the generic CmsSlotsDataResolver criteria mechanism, since that
mechanism only has a sales-channel-repository mapping for "product" -
using it for category silently dropped category.seoUrl (found via live
DDEV verification, where links rendered with an empty href).

Closes #19
csaeum merged commit 5767fd64b0 into main 2026-08-08 23:25:07 +00:00
csaeum deleted branch feature/cms-block-subcategory-columns 2026-08-08 23:25:07 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
SW-Plugins/wsc_swplugin_aiseotools!20
No description provided.