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 for Shoporamas /ajax-endpoint til filtrering af produkter. For udviklere og temadesignere.

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

Alle Shoporama-shops har et indbygget /ajax-endpoint, der returnerer produkter i JSON-format. Det gør det muligt at bygge dynamisk filtrering, lazy loading og infinite scroll uden at genindlæse siden, så kunden får en hurtig og moderne oplevelse.

Denne artikel er primært skrevet til udviklere og dem, der bygger eller tilpasser deres eget tema. Bruger du Delaware-temaet, har du allerede ajax-filtrering ud af kassen og behøver ikke selv kalde endpointet.

Sådan kalder du endpointet

Et simpelt kald, der henter produkter fra én eller flere kategorier:

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

Som standard returnerer endpointet et JSON-array med produkter. Vil du også have meta-data og pagination med, tilføjer du include_meta=1 og include_pagination=1. Så får du i stedet et objekt med products, meta og pagination.

Tilgængelige parametre

Flere af parametrene tager pipe-separerede værdier, så du kan filtrere på flere ting på én gang. Fx categories=12|34|56.

ParameterBeskrivelse
categoriesKategori-ID'er, pipe-separeret. Kombiner evt. med exclude=1 for at ekskludere i stedet
force_categoriesSom categories, men gennemtvinger kategorierne uden at lade andre filtre indsnævre dem yderligere
price_rangePrisinterval som min|max, fx 100|500
attribute_valuesID'er på attributværdier (fx farve, størrelse), pipe-separeret. Tag exclude=1 med for at ekskludere
attribute_tagsFiltrer attributværdier via deres tag i stedet for ID, fx red|blue
attribute_tags_in_stockSom attribute_tags, men kun varianter på lager
attribute_tagFiltrer på en hel attribut (ikke en bestemt værdi) ud fra dens tag, fx kun produkter der har attributten "farve"
extension[id]Filtrér på ekstrafelter. id er ekstrafelt-ID'et, og værdien kan være pipe-separeret
brandsBrand-ID'er, pipe-separeret
suppliersLeverandør-ID'er, pipe-separeret
landing_pagesLandingssides-ID'er, pipe-separeret
product_idsBestemte produkt-ID'er, pipe-separeret
atagsFiltrer efter produkt-tags
sort + sort_orderSortér resultatet. sort_order er asc eller desc (default)
limit / offsetPagination
metaBestemt meta-felt der skal med på hvert produkt. Brug _all for alle meta-felter, eller pipe-separer flere navne
only_in_stock_variantsReturnér kun varianter, der er på lager, i variant_stock-feltet på hvert produkt
include_metaSæt til 1 for at få attributter, kategorier og brands i resultatet (godt til at bygge filter-UI)
include_paginationSæt til 1 for at få offset, limit, count og total
prettySæt til 1 for pænt formateret JSON (godt til debugging)
rebuildSæt til 1 for at tvinge en ny generering af cachen for den specifikke URL

Bemærk: Parametrene category_id, tag, extra_field[..], price_from og price_to findes ikke. Brug i stedet categories, atags, extension[id] og price_range. De forkerte navne giver simpelthen 0 resultater eller bliver ignoreret, ikke en fejlmeddelelse.

Eksempel: Kategori, prisinterval og farve

Hent røde produkter mellem 100 og 500 kr. fra to kategorier, sorteret efter pris stigende:

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

Eksempel: Filtrér med ekstrafelt og få meta-data

Ekstrafelter (på engelsk "extension fields") angives med ekstrafeltets ID i klammeparenteser. Du kan finde ID'et under Indstillinger → Udvidede felter i admin. Eksempel hvor ekstrafelt 5 (fx "materiale") skal være enten "bomuld" eller "linned":

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

Felter på hvert produkt i svaret

Hvert produkt i products-arrayet har bl.a. følgende felter:

  • product_id, own_id, name, description, list_description
  • price, real_price, sale_price, price_dk (dansk formateret)
  • stock, attr_stock, variant_stock, stock_string_da
  • brand_name, supplier_id, supplier_name, profile_name
  • category_ids, category_names
  • thumbnail (200x200 fit), thumbnails (array af alle billeder i 200x200), url
  • avg_rating, online_since, delivery_time, delivery_time_not_in_stock, approx_shipping
  • has_campaigns, campaign_info
  • meta_values (kun udfyldt hvis du sender meta=...)

Hvis webshoppen har slået "skjul lager via ajax" til, vil stock, attr_stock og lagermængder i variant_stock være null, så lagertallene ikke lækker offentligt.

Caching

Endpointet caches på serveren i 12 timer pr. unik URL. Svaret sendes også med korrekt Last-Modified- og Expires-headers, så browsere og mellemliggende caches kan returnere et hurtigt 304 Not Modified, hvis indholdet er uændret. Det gør responstider hurtige, men betyder også, at ændringer på et produkt først slår igennem efter cachen udløber. Du kan tvinge en genopbygning af cachen for en bestemt URL ved at tilføje rebuild=1.

Læs mere i artiklen Cache i Shoporama, der gennemgår cache-lagene generelt.

Implementering i dit tema

For at bygge en komplet ajax-filtreret produktliste skal udvikleren typisk:

  1. Bygge filter-UI med checkboxes eller dropdowns ud fra meta.attributes, meta.brands og meta.categories
  2. Lytte på ændringer i filtrene og samle dem til en query-string
  3. Kalde /ajax med de valgte parametre
  4. Opdatere produktlisten dynamisk og vise pagination ud fra pagination.total

Tip: Læs mere om filtrering generelt i Filtrering på din webshop. Bruger du Delaware-temaet, har du allerede ajax-filtrering ud af kassen.

Ofte stillede spørgsmål

Hvor finder jeg ID'et på et ekstrafelt eller en attributværdi?

I admin under Indstillinger → Udvidede felter for ekstrafelter og under Indstillinger → Profiler for attributværdier. ID'erne vises i listen, eller i URL'en når du redigerer et felt.

Hvorfor får jeg ingen resultater, når jeg bruger category_id=123?

Fordi parameteren ikke findes. Skift til categories=123 (i flertal). Det er en af de mest almindelige fejl, når man bygger ajax-filtrering første gang. Tjek samtidig at du ikke bruger price_from/price_to eller extra_field[..], som heller ikke findes.

Mine ændringer på et produkt slår ikke igennem på /ajax. Hvad gør jeg?

Endpointet caches i 12 timer. Vent, eller hent URL'en med &rebuild=1 for at tvinge en ny generering af netop den URL.

Påvirker mange ajax-kald min hjemmesidehastighed? (Mikkel, udvikler)

Cachen sørger for, at gentagne kald er hurtige. Pas dog på med at lave et nyt kald for hvert eneste tastetryk i et søgefelt. Brug "debounce", så du først kalder, når brugeren holder pause i 200-300 ms. Browseren udnytter også If-Modified-Since, så uændrede svar kommer som 304 og næsten ingen båndbredde bruges.

Får jeg det samme resultat som på kategorisiden?

Stort set. /ajax respekterer de samme regler som ProductFactory bruger på kategorisider, så filtrering, sortering og synlighed (fx skjulte produkter) opfører sig ens.

Kan jeg lave søgning oven på /ajax? (Sofie, nyansat)

/ajax tager ikke en fritekst-søgeparameter. Til søgning skal du bruge Shoporamas dedikerede søge-endpoint i temaet (typisk /search) eller filtrere på product_ids, hvis du selv står for søgningen og blot vil hente data om en kendt liste af produkter.

Hvor mange produkter må jeg hente i ét kald? (Jonas, skala)

Der er ingen hård grænse i koden, men hold dig praktisk under et par hundrede pr. kald for at holde JSON-payloaden lille og responsen hurtig. Brug limit og offset til at sidetælle, eller hent kun næste batch når brugeren scroller.

Bliver mine kunders lagerantal eksponeret offentligt? (Malene, marketing)

Som udgangspunkt indeholder svaret lagerantal. Skal det skjules (så konkurrenter eller robotter ikke kan se hvor meget I har på lager), kan din udvikler aktivere "skjul lager via ajax" på webshoppen, hvorefter stock-felterne sendes som null.

Kan jeg bruge /ajax som et "rigtigt" REST-API? (Mikkel, udvikler)

Nej, det er et offentligt cache-venligt produkt-endpoint til frontend-brug. Skal du oprette, opdatere eller integrere på et dybere niveau, så brug det egentlige REST API i stedet, der kræver en API-nøgle.

Skal jeg være bekymret for, at filtreringen virker forskelligt for kunder i forskellige sprog?

Endpointet kører i samme webshop-kontekst som forsiden, så priser, valuta og synlighed følger den webshop, kaldet rammer. Har du flere webshops eller sprog, så husk at hver webshop har sin egen URL, og dermed sin egen /ajax-cache.

Skal vi hjælpe med at bygge ajax-filtrering ind i dit tema, eller har du tekniske spørgsmål? Skriv til support@shoporama.dk.