AjaxListing 1.1.15 Help

Backend

Wie aus der Elementkonfiguration eine Store-API-Abfrage wird.

Kein Resolver

Das Plugin bringt keinen serverseitigen CMS-Element-Resolver mit. Die Twig-Vorlage storefront/element/cms-element-ajax-listing.html.twig baut die Filterabfrage und legt sie als data-ajax-listing-options an das Element; das Storefront-JavaScript reicht sie unverändert an POST /store-api/product weiter.

Der Adminbereich geht einen anderen Weg: collect() in src/main.ts baut dieselbe Abfrage als Criteria und holt die Produkte über die Admin-API. Beide Seiten müssen daher dieselbe Abbildung beherrschen — festgehalten wird das durch src/Test/fixtures/filter-cases.json, das von beiden Testseiten gelesen wird.

Die Abbildung

Vergleich

erzeugte Abfrage

ist gleich

{field, value, type: equals}

ist ungleich

{type: not, operator: and, queries: [equals]}

≥ / ≤

{field, type: range, parameters: {gte}} bzw. {lte}

liegt zwischen

range mit gte und lte; fehlt die Obergrenze, bleibt es ein gte

enthält

{field, value, type: contains}

Alle Bedingungen zusammen stehen in einer multi/and-Hülle. Eine Zeile ohne Wert wird übersprungen. Bleibt keine Zeile übrig, sendet das Element bewusst {field: 'id', value: null, type: 'equals'} — eine Abfrage, die nichts trifft.

Welche Felder angeboten werden

Nicht jedes Feld der Produkt-Entität taugt als Filter. config/index.ts entscheidet anhand der Merker der Entitätsdefinition:

  • runtime — wird zur Laufzeit berechnet und kann gar nicht gefiltert werden (translated, variation).

  • read_protected — nennt die erlaubten API-Quellen. Fehlt SalesChannelApiSource, weist die Store-API den Filter ab.

  • api_criteria_aware — sticht die Leseeinschränkung: price darf gefiltert werden, obwohl es nur die Admin-API lesen darf. Genau daran unterscheidet es sich von prices.

  • Eine Zu-viele-Verknüpfung hat keine eigene Spalte; ihr localField ist die Produkt-Id. Sie wird deshalb als <name>.id angeboten — sonst filterte »Kategorien« in Wahrheit auf das Produkt selbst.

Dazu kommt die Liste NOT_OFFERED: Felder, die zwar funktionieren, aber in einem Produktlisting nichts zu suchen haben. Sie ist im Quelltext je Gruppe begründet.

Feldnamen

Shopware führt kein allgemeines Register übersetzter Feldnamen — nur für Entitäten (global.entities.*). Die Beschriftungen kommen deshalb aus einer Kette:

  1. plugin.leoparden.AjaxListing.config.fields.<feld> — der eigene Textbaustein,

  2. sw-product-stream.filter.values.<feld> — die dynamischen Produktgruppen, die dasselbe Problem lösen und rund 70 Feldnamen zweisprachig mitbringen,

  3. global.entities.<entität> bei Verknüpfungen,

  4. sonst der technische Name.

Der eigene Baustein steht vorn, damit eine Formulierung überschrieben werden kann, die im Streamzusammenhang passt und hier nicht.

Last modified: 28 August 2026