Nödsituation

Vid nödsituationer eller driftstörningar kan du skicka ett SMS till vår jourtelefon

Jourtelefon (endast SMS)

+45 29 70 15 95

Skicka ett SMS med följande information:

  • Ditt namn och din webbshop
  • Beskrivning av problemet
  • Ditt telefonnummer för återuppringning

Anteckningar: Denna tjänst är endast avsedd för kritiska situationer där din webbshop ligger nere eller har allvarliga problem. För vanlig support, vänligen använd våra normala supportkanaler.

Ajax-filtrering

Teknisk dokumentation för Shoporamas /ajax-slutpunkt för filtrering av produkter. För utvecklare och temadesigners.

Lästid: ca {åtta} minuter
Shopejer Utvecklare

Alla Shoporama-butiker har en inbyggd /ajax-ändpunkt som returnerar produkter i JSON-format. Det gör det möjligt att bygga dynamisk filtrering, lazy loading och oändlig rullning utan att ladda om sidan, så att kunden får en snabb och modern upplevelse.

Den här artikeln riktar sig främst till utvecklare och dem som bygger eller anpassar sitt eget tema. Om du använder Delaware-temat har du redan ajax-filtrering som standard och behöver inte själv anropa endpointen.

Så här anropar du endpointen

Ett enkelt anrop som hämtar produkter från en eller flera kategorier:

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

Som standard returnerar endpointen en JSON-array med produkter. Om du även vill ha med metadata och paginering lägger du till include_meta=1 och include_pagination=1. Då får du istället ett objekt med products, meta och pagination.

Tillgängliga parametrar

Flera av parametrarna tar pipe-separerade värden, så att du kan filtrera på flera saker samtidigt. Till exempel categories=12|34|56.

ParameterBeskrivning
categoriesKategori-ID:n, separerade med vertikalstreck. Om flera ID:n anges returneras produkter som ingår i minst en av kategorierna (OR). Lägg till match=all för att endast få produkter som ingår i alla angivna kategorier (AND)
force_categoriesSamma som categories, men tvingar fram kategorierna utan att låta andra filter begränsa dem ytterligare
price_rangePrisintervall i form av min|max, t.ex. 100|500
attribute_valuesID:n på attributvärden (t.ex. färg, storlek), separerade med vertikalstreck. Flera värden matchas som OR. Lägg till match=all för att kräva att produkten har alla angivna värden (AND), t.ex. både en färg och en storlek
attribute_tagsFiltrera attributvärden via deras tagg istället för ID, t.ex. red|blue
attribute_tags_in_stockSamma som attribute_tags, men endast varianter som finns i lager
attribute_tagFiltrerar på ett helt attribut (inte ett specifikt värde) utifrån dess tagg, t.ex. endast produkter som har attributet ”färg”
extension[id]Filtrera på extrafält. id är extrafältets ID, och värdet kan vara separerat med vertikalstreck
brandsVarumärkes-ID:n, separerade med vertikalstreck
suppliersLeverantörs-ID:n, separerade med vertikalstreck
landing_pagesLandningssid-ID:n, separerade med vertikalstreck
product_idsSpecifika produkt-ID:n, separerade med vertikalstreck
atagsFiltrera efter produkttaggar
sort + sort_orderSortera resultatet. sort_order är asc eller desc (standard)
limit / offsetPaginering. limit kan högst vara 1000, och högre värden beskärs automatiskt
metaSpecifikt meta-fält som ska ingå i varje produkt. Använd _all för alla meta-fält, eller separera flera namn med pipe-tecken
only_in_stock_variantsReturnera endast varianter som finns i lager i fältet variant_stock för varje produkt
include_metaStäll in på 1 för att få med attribut, kategorier och varumärken i resultatet (bra för att bygga filtergränssnitt)
include_paginationStäll in på 1 för att få offset, limit, count och total
prettyStäll in på 1 för snyggt formaterad JSON (bra för felsökning)
rebuildStäll in på 1 för att tvinga fram en ny generering av cachen för den specifika URL:en

Filtrering med AND (match=all)

När du skickar flera kategorier eller attributvärden matchar slutpunkten som standard med OR: en produkt ingår om den stämmer överens med minst ett av värdena. Det fungerar bra för breda översikter, men vid facettfiltrering vill du ofta ha det omvända, nämligen endast de produkter som matchar alla de valda värdena samtidigt.

Lägg till match=all för att växla till AND-logik. Då måste produkten ha vart och ett av de angivna värdena för att ingå. Det är precis vad du behöver när en kund väljer både en färg och en storlek i ditt filter:

// Endast produkter som har BÅDE värdet 401815 OCH 401822
fetch('/ajax?attribute_values=401815|401822&match=all&limit=50')
  .then(response => response.json())
  .then(products => { /* ... */ });

match=all fungerar både på categories och attribute_values. Utan parametern används OR som tidigare.

Observera: Den äldre parametern exclude=1 gör exakt samma sak som match=all och fungerar fortfarande av hänsyn till bakåtkompatibilitet. Namnet är missvisande, eftersom den inte exkluderar någonting, så använd match=all i ny kod.

Observera: Parametrarna category_id, tag, extra_field[..], price_from och price_to finns inte längre. Använd istället categories, atags, extension[id] och price_range. Felaktiga namn ger helt enkelt 0 resultat eller ignoreras, utan att ett felmeddelande visas.

Exempel: Kategori, prisintervall och färg

Hämta röda produkter mellan 100 och 500 kr från två kategorier, sorterade efter pris i stigande ordning:

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));

Exempel: Filtrera med extrafält och hämta metadata

Extra fält (på engelska ”extension fields”) anges med fältets ID inom klammerparenteser. Du hittar ID:t under Inställningar → Utökade fält i admin. Exempel där extrafält 5 (t.ex. ”material”) ska vara antingen ”bomull” eller ”linne”:

// extension[5]=bomuld|linned
fetch('/ajax?categories=12&extension[5]=' + encodeURIComponent('bomuld|linned') + '&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);
  });

Fält för varje produkt i svaret

Varje produkt i products-arrayen har bland annat följande fält:

JSON-svar fra /ajax-endpointet med produktfelter som product_id, own_id, name, price, price_dk, stock, og variant_stock med lagervarianter
JSON-svaret från /ajax-ändpunkten på mortensbutik.dk. Varje produkt har fält som product_id, name, price, price_dk, stock och variant_stock med lager per variant.
  • product_id, own_id, name, description, list_description
  • price, real_price, sale_price, price_dk (formaterat enligt danska standarder)
  • stock, attr_stock, variant_stock, stock_string_da
  • brand_name, supplier_id, supplier_name, profile_name
  • category_ids, category_names
  • miniatyrbild (200x200), miniatyrbilder (array med alla bilder i 200x200), url
  • genomsnittligt_betyg, online_sedan, leveranstid, leveranstid_vid_slut_i_lager, ungefärlig_frakt
  • har_kampanjer, kampanjinfo
  • meta_values (fylls endast i om du skickar meta=...)

Om webbutiken har aktiverat "dölj lager via ajax" kommer stock, attr_stock och lagerkvantiteter i variant_stock att vara null, så att lagernumren inte läcker ut offentligt.

Cachelagring

Endpunkten cachas på servern i 12 timmar per unik URL. Svaret skickas också med korrekta Last-Modified- och Expires-headers, så att webbläsare och mellanliggande cacher kan returnera ett snabbt 304 Not Modified om innehållet är oförändrat. Detta ger snabba svarstider, men innebär också att ändringar av en produkt först träder i kraft efter att cachen har löpt ut. Du kan tvinga fram en ombyggnad av cachen för en viss URL genom att lägga till rebuild=1.

Läs mer i artikeln Cache i Shoporama, som går igenom cache-lagren i allmänhet.

Implementering i ditt tema

För att bygga en komplett AJAX-filtrerad produktlista måste utvecklaren vanligtvis:

  1. Skapa ett filtergränssnitt med kryssrutor eller rullgardinsmenyer baserat på meta.attributes, meta.brands och meta.categories
  2. Övervaka ändringar i filtren och sammanställa dem till en frågesträng
  3. Anropa /ajax med de valda parametrarna
  4. Uppdatera produktlistan dynamiskt och visa paginering utifrån pagination.total

Tips: Läs mer om filtrering i allmänhet i avsnittet Filtrering i din webbshop. Om du använder Delaware-temat har du redan AJAX-filtrering som standard.

Vanliga frågor

Var hittar jag ID:t för ett extrafält eller ett attributvärde?

I admin under Inställningar → Utökade fält för extrafält och under Inställningar → Profiler för attributvärden. ID:n visas i listan eller i URL:en när du redigerar ett fält.

Varför får jag inga resultat när jag använder category_id=123?

Därför att parametern inte finns. Byt till categories=123 (i plural). Det är ett av de vanligaste felen när man skapar AJAX-filtrering för första gången. Kontrollera samtidigt att du inte använderprice_from/price_to eller extra_field[...], som inte heller finns.

Mina ändringar på en produkt syns inte på /ajax. Vad ska jag göra?

Endpunkten cachas i 12 timmar. Vänta, eller hämta URL:en med &rebuild=1 för att tvinga fram en ny generering av just den URL:en.

Påverkar många AJAX-anrop hastigheten på min webbplats? (Mikkel, utvecklare)

Cachen ser till att upprepade anrop går snabbt. Var dock försiktig med att göra ett nytt anrop för varje enskilt tangenttryck i ett sökfält. Använd ”debounce” så att du först skickar en begäran när användaren har väntat i 200–300 ms. Webbläsaren utnyttjar också If-Modified-Since, så oförändrade svar returneras som 304 och nästan ingen bandbredd förbrukas.

Får jag samma resultat som på kategorisidan?

I stort sett. /ajax följer samma regler som ProductFactory använder på kategorisidorna, så filtrering, sortering och synlighet (t.ex. dolda produkter) fungerar på samma sätt.

Kan jag göra en sökning på /ajax? (Sofie, nyanställd)

/ajax accepterar inte en fritextsökningsparameter. För sökning måste du använda Shoporamas dedikerade sök-endpoint i temat (vanligtvis /search) eller filtrera på product_ids om du själv sköter sökningen och bara vill hämta data om en känd lista med produkter.

Hur många produkter får jag hämta i ett enda anrop? (Jonas, skala)

Du kan hämta upp till 1 000 produkter i ett enda anrop. Om du begär fler begränsas svaret automatiskt till 1 000, och butiken får samtidigt ett meddelande i admin under Meddelanden så att du kan upptäcka det. I praktiken bör du ligga något lägre. Ett par hundra per förfrågan håller JSON-payloaden liten och svaret snabbt, vilket är särskilt viktigt för mobilanvändare. Använd limit och offset för att räkna sidor, eller hämta nästa batch först när användaren bläddrar.

Blir mina kunders lagerstatus offentliggjord? (Malene, marknadsföring)

Som utgångspunkt innehåller svaret lagerantal. Om det ska döljas (så att konkurrenter eller robotar inte kan se hur mycket ni har i lager) kan er utvecklare aktivera ”dölj lager via ajax” i webbutiken, varpå lagerfälten skickas som null.

Kan jag använda /ajax som ett ”riktigt” REST-API? (Mikkel, utvecklare)

Nej, det är en offentlig, cachevänlig produkt-endpoint avsedd för frontend-användning. Om du behöver skapa, uppdatera eller integrera på en djupare nivå ska du istället använda det egentliga REST-API:et, som kräver en API-nyckel.

Behöver jag oroa mig för att filtreringen fungerar olika för kunder på olika språk?

Endpunkten körs i samma webbshop-kontext som startsidan, så priser, valuta och synlighet följer den webbshop som kallas ramverk. Om du har flera webbshoppar eller språk, kom ihåg att varje webbshop har sin egen URL och därmed sin egen /ajax-cache.

Behöver du hjälp med att bygga in AJAX-filtrering i ditt tema, eller har du tekniska frågor? Skriv till support@shoporama.dk.