Notsituation

Bei Notfällen oder Pannen können Sie eine SMS an unsere Notfall-Hotline senden

Telefon für den Bereitschaftsdienst (nur SMS)

+45 29 70 15 95

Senden Sie eine SMS mit den folgenden Informationen:

  • Ihr Name und Ihr Webshop
  • Beschreibung des Problems
  • Ihre Rückrufnummer

Anmerkungen: Dieser Service ist nur für kritische Situationen gedacht, in denen Ihr Webshop ausfällt oder schwerwiegende Probleme aufweist. Für regelmäßigen Support nutzen Sie bitte unsere normalen Supportkanäle.

Ajax-Filterung

Technische Dokumentation für den /ajax-Endpunkt von Shoporama zum Filtern von Produkten. Für Entwickler und Themendesigner.

Læsetid: ca. 20 minutter
Schopejer Entwickler

Alle Shoporama-Shops verfügen über einen integrierten /ajax-Endpunkt, der Produkte im JSON-Format zurückgibt. Dies ermöglicht die Implementierung von dynamischer Filterung, Lazy Loading und unendlichem Scrollen, ohne dass die Seite neu geladen werden muss, sodass der Kunde ein schnelles und modernes Erlebnis erhält.

Dieser Artikel richtet sich in erster Linie an Entwickler und alle, die ihr eigenes Theme erstellen oder anpassen. Wenn Sie das Delaware-Theme verwenden, steht Ihnen die Ajax-Filterung bereits standardmäßig zur Verfügung, sodass Sie den Endpunkt nicht selbst aufrufen müssen.

So rufen Sie den Endpunkt auf

Ein einfacher Aufruf, der Produkte aus einer oder mehreren Kategorien abruft:

fetch('/ajax?categories=123&limit=24')
  .then(response => response.json())
  .then(products => {
    products.forEach(p => console.log(p.name, p.price));
  });

Standardmäßig gibt der Endpunkt ein JSON-Array mit Produkten zurück. Wenn du zusätzlich Metadaten und Paginierung erhalten möchtest, füge include_meta=1 und include_pagination=1 hinzu. Dann erhältst du stattdessen ein Objekt mit den Elementen „products“, „meta“ und „pagination“.

Verfügbare Parameter

Viele der Parameter akzeptieren durch Pipe-Zeichen getrennte Werte, sodass du nach mehreren Kriterien gleichzeitig filtern kannst. Z. B. categories=12|34|56.

ParameterBeschreibung
categoriesKategorie-IDs, durch Pipe getrennt. Bei mehreren IDs werden Produkte zurückgegeben, die in mindestens einer der Kategorien enthalten sind (ODER). Fügen Sie „match=all“ hinzu, um nur Produkte zu erhalten, die in allen angegebenen Kategorien enthalten sind (UND)
force_categoriesWie „categories“, erzwingt jedoch die Kategorien, ohne dass andere Filter diese weiter einschränken
price_rangePreisspanne im Format min|max, z. B. 100|500
attribute_valuesIDs von Attributwerten (z. B. Farbe, Größe), durch Pipe-Zeichen getrennt. Mehrere Werte werden als „ODER“ abgeglichen. Fügen Sie „match=all“ hinzu, um zu verlangen, dass das Produkt alle angegebenen Werte aufweist (UND), z. B. sowohl eine Farbe als auch eine Größe
attribute_tagsFiltere Attributwerte anhand ihres Tags statt anhand der ID, z. B. red|blue
attribute_tags_in_stockWie „attribute_tags“, jedoch nur Varianten, die vorrätig sind
attribute_tagFiltert nach einem gesamten Attribut (nicht nach einem bestimmten Wert) anhand seines Tags, z. B. nur Produkte, die das Attribut „Farbe“ haben
extension[id]Nach Zusatzfeldern filtern. „id“ ist die ID des Zusatzfeldes, und der Wert kann durch Pipe-Zeichen getrennt sein
brandsMarken-IDs, durch Pipe getrennt
suppliersLieferanten-IDs, durch Pipe getrennt
landing_pagesLanding-Page-IDs, durch Pipe getrennt
product_idsBestimmte Produkt-IDs, durch Pipe getrennt
TagsNach Produkt-Tags filtern
sort + sort_orderErgebnis sortieren. sort_order ist asc oder desc (Standard)
limit / offsetPaginierung. „limit“ darf höchstens 1000 betragen; höhere Werte werden automatisch gekürzt
metaBestimmtes Meta-Feld, das bei jedem Produkt angezeigt werden soll. Verwende _all für alle Meta-Felder oder trenne mehrere Namen durch ein Pipe-Zeichen
only_in_stock_variantsGibt nur Varianten zurück, die im Feld „variant_stock“ jedes Produkts als vorrätig gekennzeichnet sind
include_metaSetze den Wert auf 1, um Attribute, Kategorien und Marken in das Ergebnis einzubeziehen (gut geeignet zum Erstellen einer Filter-Benutzeroberfläche)
include_paginationSetze den Wert auf 1, um „offset“, „limit“, „count“ und „total“ zu erhalten
prettyAuf 1 setzen, um schön formatiertes JSON zu erhalten (gut zum Debuggen)
rebuildSetzen Sie diesen Wert auf 1, um eine Neugenerierung des Caches für die jeweilige URL zu erzwingen

Filterung mit AND (match=all)

Wenn du mehrere Kategorien oder Attributwerte übermittelst, führt der Endpunkt standardmäßig eine OR-Vergleichsoperation durch: Ein Produkt wird berücksichtigt, wenn es mindestens einem der Werte entspricht. Das eignet sich gut für umfassende Übersichten, aber bei der Facettenfilterung ist oft das Gegenteil gewünscht, nämlich nur die Produkte, die allen ausgewählten Werten gleichzeitig entsprechen.

Fügen Sie „match=all“ hinzu, um zur UND-Logik zu wechseln. Dann muss das Produkt jeden einzelnen der angegebenen Werte aufweisen, um berücksichtigt zu werden. Genau das benötigen Sie, wenn ein Kunde in Ihrem Filter sowohl eine Farbe als auch eine Größe auswählt:

// Nur Produkte, die SOWOHL den Wert 401815 ALS AUCH 401822 haben
fetch('/ajax?attribute_values=401815|401822&match=all&limit=50')
  .then(response => response.json())
  .then(products => { /* ... */ });

„match=all“ wirkt sowohl auf „categories“ als auch auf „attribute_values“. Ohne diesen Parameter wird wie bisher „OR“ verwendet.

Hinweis: Der ältere Parameter `exclude=1` hat genau dieselbe Wirkung wie `match=all` und wird aus Gründen der Abwärtskompatibilität weiterhin unterstützt. Der Name ist irreführend, da er nichts ausschließt; verwenden Sie daher in neuem Code `match=all`.

Hinweis: Die Parameter „category_id“, „tag“, „extra_field[..]“, „price_from“ und „price_to“ existieren nicht mehr. Verwenden Sie stattdessen „categories“, „tags“, „extension[id]“ und „price_range“. Die falschen Bezeichnungen liefern einfach 0 Ergebnisse oder werden ignoriert – es erscheint keine Fehlermeldung.

Beispiel: Kategorie, Preisbereich und Farbe

Rufe rote Produkte zwischen 100 und 500 DKK aus zwei Kategorien ab, sortiert nach aufsteigendem Preis:

const params = new URLSearchParams({
  categories: '12|34',
  price_range: '100|500',
  attribute_tags: 'red',
  sort: 'price',
  sort_order: 'asc',
  limit: 24
});

fetch('/ajax?' + params)
  .then(r => r.json())
  .then(products => renderProducts(products));

Beispiel: Nach Zusatzfeldern filtern und Metadaten abrufen

Zusatzfelder (auf Englisch „extension fields“) werden durch die ID des Zusatzfeldes in eckigen Klammern angegeben. Die ID findest du unter „Einstellungen“ → „Erweiterte Felder“ im Admin-Bereich. Beispiel, bei dem das Erweiterungsfeld 5 (z. B. „Material“) entweder „Baumwolle“ oder „Leinen“ sein muss:

// extension[5]=Baumwolle|Leinen
fetch('/ajax?categories=12&extension[5]=' + encodeURIComponent('Baumwolle|Leinen') + '&include_meta=1&include_pagination=1&limit=24')
  .then(r => r.json())
  .then(data => {
    console.log(data.products);
    console.log(data.meta.attributes);
    console.log(data.pagination);
  });

Felder jedes Produkts in der Antwort

Jedes Produkt im „products“-Array verfügt unter anderem über folgende Felder:

JSON-svar fra /ajax-endpointet med produktfelter som product_id, own_id, name, price, price_dk, stock, og variant_stock med lagervarianter
Die JSON-Antwort vom /ajax-Endpunkt auf mortensbutik.dk. Jedes Produkt verfügt über Felder wie product_id, name, price, price_dk, stock und variant_stock mit dem Lagerbestand pro Variante.
  • product_id, own_id, name, description, list_description
  • price, real_price, sale_price, price_dk (im dänischen Format)
  • stock, attr_stock, variant_stock, stock_string_da
  • brand_name, supplier_id, supplier_name, profile_name
  • category_ids, category_names
  • thumbnail (200x200), thumbnails (Array aller Bilder im Format 200x200), url
  • Durchschnittliche Bewertung, seit wann online, Lieferzeit, Lieferzeit bei Nichtverfügbarkeit, ungefähre Versandzeit
  • has_campaigns, campaign_info
  • meta_values (wird nur ausgefüllt, wenn Sie meta=... senden)

Wenn im Webshop die Option „Lagerbestand über Ajax ausblenden“ aktiviert ist, sind stock, attr_stock und die Lagerbestände in variant_stock null, damit die Lagerbestände nicht öffentlich sichtbar sind.

Caching

Der Endpunkt wird auf dem Server für 12 Stunden pro eindeutiger URL zwischengespeichert. Die Antwort wird zudem mit korrekten „Last-Modified“- und „Expires“-Headern gesendet, sodass Browser und Zwischenspeicher schnell einen 304 Not Modified-Status zurückgeben können, wenn der Inhalt unverändert ist. Das sorgt für schnelle Antwortzeiten, bedeutet aber auch, dass Änderungen an einem Produkt erst nach Ablauf des Caches wirksam werden. Du kannst einen Neuaufbau des Caches für eine bestimmte URL erzwingen, indem du „rebuild=1“ hinzufügst.

Weitere Informationen finden Sie im Artikel „Cache in Shoporama“, der die Cache-Ebenen allgemein erläutert.

Implementierung in Ihrem Theme

Um eine vollständige, per Ajax gefilterte Produktliste zu erstellen, muss der Entwickler in der Regel:

  1. Erstellen einer Filter-Benutzeroberfläche mit Kontrollkästchen oder Dropdown-Menüs auf Basis von „meta.attributes“, „meta.brands“ und „meta.categories“
  2. Änderungen an den Filtern überwachen und diese zu einer Abfragezeichenfolge zusammenfassen
  3. /ajax mit den ausgewählten Parametern aufrufen
  4. Die Produktliste dynamisch aktualisieren und die Paginierung basierend auf ` pagination.total` anzeigen

Tipp: Erfahren Sie mehr über die Filterung im Allgemeinen unter „Filterung in Ihrem Webshop“. Wenn Sie das Delaware-Theme verwenden, steht Ihnen die Ajax-Filterung bereits standardmäßig zur Verfügung.

Häufig gestellte Fragen

Wo finde ich die ID eines Zusatzfeldes oder eines Attributwertes?

Im Admin-Bereich unter „Einstellungen“ → „Erweiterte Felder“ für Zusatzfelder und unter „Einstellungen“ → „Profile“ für Attributwerte. Die IDs werden in der Liste oder in der URL angezeigt, wenn du ein Feld bearbeitest.

Warum erhalte ich keine Ergebnisse, wenn ich „category_id=123“ verwende?

Weil der Parameter nicht existiert. Wechsle zu categories=123 (im Plural). Das ist einer der häufigsten Fehler, wenn man zum ersten Mal eine Ajax-Filterung erstellt. Überprüfe gleichzeitig, ob du nicht„price_from/price_to“ oder „extra_field[..]“ verwendest, da diese ebenfalls nicht existieren.

Meine Änderungen an einem Produkt werden unter /ajax nicht übernommen. Was soll ich tun?

Der Endpunkt wird 12 Stunden lang zwischengespeichert. Warte ab oder rufe die URL mit &rebuild=1 auf, um eine Neugenerierung genau dieser URL zu erzwingen.

Beeinträchtigen viele AJAX-Aufrufe die Geschwindigkeit meiner Website? (Mikkel, Entwickler)

Der Cache sorgt dafür, dass wiederholte Aufrufe schnell erfolgen. Achte jedoch darauf, nicht bei jedem einzelnen Tastendruck in ein Suchfeld einen neuen Aufruf zu generieren. Verwende „Debounce“, damit der Aufruf erst erfolgt, wenn der Nutzer 200–300 ms lang pausiert. Der Browser nutzt außerdem „If-Modified-Since“, sodass unveränderte Antworten als 304 zurückgegeben werden und fast keine Bandbreite verbraucht wird.

Erhalte ich das gleiche Ergebnis wie auf der Kategorieseite?

Im Großen und Ganzen. /ajax befolgt dieselben Regeln, die ProductFactory auf Kategorieseiten anwendet, sodass Filterung, Sortierung und Sichtbarkeit (z. B. ausgeblendete Produkte) sich gleich verhalten.

Kann ich eine Suche über /ajax durchführen? (Sofie, neue Mitarbeiterin)

/ajax akzeptiert keinen Freitext-Suchparameter. Für die Suche musst du den dedizierten Such-Endpunkt von Shoporama im Theme verwenden (typischerweise /search) oder nach product_ids filtern, wenn du die Suche selbst durchführst und lediglich Daten zu einer bekannten Liste von Produkten abrufen möchtest.

Wie viele Produkte darf ich in einem Aufruf abrufen? (Jonas, Skalierung)

Du kannst bis zu 1.000 Produkte in einem Aufruf abrufen. Wenn du mehr anforderst, wird die Antwort automatisch auf 1.000 begrenzt, und der Shop erhält gleichzeitig eine Benachrichtigung im Admin-Bereich unter „Benachrichtigungen“, damit du dies bemerken kannst. In der Praxis solltest du dich etwas darunter bewegen. Ein paar Hundert pro Aufruf halten die JSON-Nutzlast klein und die Antwort schnell, was insbesondere für Kunden auf Mobilgeräten wichtig ist. Verwende „limit“ und „offset“, um die Seiten zu nummerieren, oder rufe den nächsten Stapel erst ab, wenn der Nutzer scrollt.

Werden die Lagerbestände meiner Kunden öffentlich angezeigt? (Malene, Marketing)

Grundsätzlich enthält die Antwort die Lagerbestände. Soll dies verborgen werden (damit Konkurrenten oder Bots nicht sehen können, wie viel ihr auf Lager habt), kann euer Entwickler im Webshop die Option „Lagerbestand über Ajax verbergen“ aktivieren, woraufhin die Lagerbestandsfelder als „null“ gesendet werden.

Kann ich /ajax als „echte“ REST-API verwenden? (Mikkel, Entwickler)

Nein, es handelt sich um einen öffentlichen, cache-freundlichen Produkt-Endpunkt für die Frontend-Nutzung. Wenn du auf einer tieferen Ebene Daten anlegen, aktualisieren oder integrieren möchtest, verwende stattdessen die eigentliche REST-API, für die ein API-Schlüssel erforderlich ist.

Muss ich mir Sorgen machen, dass die Filterung für Kunden in verschiedenen Sprachen unterschiedlich funktioniert?

Der Endpunkt läuft im selben Webshop-Kontext wie die Startseite, sodass Preise, Währung und Sichtbarkeit den Rahmenbedingungen des jeweiligen Webshops folgen. Wenn du mehrere Webshops oder Sprachen hast, denke daran, dass jeder Webshop seine eigene URL und somit seinen eigenen /ajax-Cache hat.

Sollen wir Ihnen dabei helfen, die Ajax-Filterung in Ihr Theme zu integrieren, oder haben Sie technische Fragen? Schreiben Sie an support@shoporama.dk.