Bestil opringning

Udfyld formularen, så ringer vi dig op hurtigst muligt

Nødsituation

Ved akutte situationer eller nedbrud kan du sende en SMS til vores vagttelefon

Vagttelefon (kun SMS)

+45 29 70 15 95

Send en SMS med følgende information:

  • Dit navn og webshop
  • Beskrivelse af problemet
  • Dit telefonnummer for tilbageringning

Bemærk: Denne service er kun til kritiske situationer hvor din webshop er nede eller har alvorlige problemer. For almindelig support, brug venligst vores normale supportkanaler.

Shoporama Templates

Herunder finder du information til hvordan du udvikler et Shoporama-tema.

Overblik

Overordnet set består et Shoporama-tema er en række html-filer der ligger i en mappe på vores ftp-server. Template-sproget i de enkelte filer er Smarty, som nævnes herunder.

I de enkelte templates er der adgang til en række objekter og metoder. Dem kan du læse mere om i vores Template API.

Kontakt os på support@shoporama.dk hvis du har spørgsmål.

Udviklingsmiljø

For at gøre udviklingen af Shoporama temaer nemmere og hurtigere, har vi udviklet Hackorama - et lokalt udviklingsmiljø der simulerer Shoporamas produktionsmiljø.

Hackorama gør det muligt at udvikle og teste dine temaer lokalt uden at skulle deploye til produktion. Dette giver dig hurtigere feedback og en mere effektiv udviklingsproces.

Funktioner

  • Lokal API-datahentning med cache-system
  • Smarty 4 template engine med samme delimiters som Shoporama
  • Wrapper-klasser der efterligner Shoporamas "Safe*" klasser
  • Automatisk billedskalering og caching
  • Simuleret kundelogin og checkout-flow
  • Debug-værktøjer og logging

Kom i gang

Følg disse trin for at komme i gang med Hackorama:

# 1. Klon repository
git clone https://github.com/blinksbjerg/hackorama.git
cd hackorama

# 2. Konfigurer din API-nøgle i setup.php
# Rediger setup.php og indsæt din Shoporama API-nøgle

# 3. Start lokal PHP server
php -S localhost:8080

# 4. Åbn din browser
# Naviger til http://localhost:8080

Eksempel: Test af produktvisning

Her er et eksempel på hvordan du kan teste din produktvisning i Hackorama:

# I din template fil (f.eks. product.html)
<div class="product-detail">
    <h1><{$product->getName()|escape}></h1>
    <div class="price">
        <{$product->getPrice()|currency}>
    </div>
    <div class="description">
        <{$product->getDescription()}>
    </div>
</div>

# Test i Hackorama ved at navigere til:
# http://localhost:8080/product?id=123

Tip: Hackorama inkluderer Alaska2-temaet som eksempel. Du kan bruge dette som udgangspunkt for dit eget tema eller som reference for best practices.

Bemærk: Hackorama er ikke en 1:1 kopi af Shoporamas produktionsmiljø. Det understøtter de basale funktioner der er nødvendige for lokal tema-udvikling, men ikke alle avancerede features er implementeret. Dette er designet til at give dig et hurtigt og effektivt udviklingsmiljø for de mest almindelige use cases.

Læs mere om Hackorama og se den fulde dokumentation på GitHub.

Smarty

Motoren i vores template-system er baseret på Smarty.

Vi har af bagudkompatible årsager version 2.6 installeret, men den vedligeholder vi ikke længere, og vi anbefaler at alle bruger version 4.x. Versionen indstilles under indstillinger for shoppen.

Bemærk at denne dokumentation tager kun højde for version 4.x.

Forskellen på standard Smarty og vores er at vi bruger <{ og }> som delimiter. Dvs. syntaksen er:

<h1>Velkommen til <{$webshop->getName()|escape}></h1>

Tips

Undersøg indhold

Hvis du er i tvivl om hvad en variabel er, eller hvad en funktion returerer, kan du køre den igennem var_dump. Hvis du har fat i et objekt vil du altid kunne se hvilke metoder der findes i vores Template API.

Du bruger var_dump på følgende måde:

<{$order|var_dump}>
Check objekter

I nogle tilfælde er det relevant at sikre sig, at hvis man bruger en variabel som et objekt, at det også er et objekt. Ellers vil templaten ikke virke. Vi stiller nogle globale variabler som fx $product, og $webshop med flere. For de variabler er det ikke nødvendigt. Der kan checkes på en af følgende måder:

<{* Typisk tilstrækkelig *}>
<{if $profile}>
	<{$profile->getName()}>
<{/if}>

<{* Lidt grundigere *}>
<{if is_object($profile)}>
	<{$profile->getName()}>
<{/if}>

<{* Meget grundig *}>
<{if is_a($profile, "SafeProfile")}>
	<{$profile->getName()}>
<{/if}>
Debug

Hvis du vil se hvilke variabler der er tilgælgelig på den side du udvikler kan du sætte Smarty i debug-mode og se variablerne i et nye vindue. Indsæt følgende kode i din template:

<{debug}>

Læs mere om Smarty4 her: Smarty 4 Documentation.

Tilgængelige funktioner og modifiers

I Shoporama har du adgang til et udvalgt sæt af Smarty modifiers og funktioner som er godkendt af sikkerhedsmæssige årsager:

Modifiers
String manipulation
|strip_tags - Fjerner HTML tags
|substr:start:length - Udtrækker del af streng
|trim - Fjerner whitespace
|ucfirst - Stort begyndelsesbogstav
Arrays og tal
|implode:"," - Samler array til streng
|explode:"," - Deler streng til array
|count - Tæller elementer
|floor - Runder ned
|strlen - Længde af streng
Dato og andet
|strtotime - Konverterer dato til timestamp
|md5 - MD5 hash
Funktioner i conditionals
Validering
isset($var) - Tjekker om variabel er sat
is_array($var) - Tjekker om det er et array
is_object($var) - Tjekker om det er et objekt
intval($var) - Konverterer til heltal
Arrays og templates
in_array($needle, $haystack) - Søger i array
template_exists('file.html') - Tjekker om template findes
Eksempel:
<{if in_array($product->getProductId(), $featured_ids) && isset($show_badge)}>
    Featured
<{/if}>

Filstruktur

Du får ftp-adgang til din shop, og i roden af dit bibliotek skal du lægge dit tema. Navnet på mappen er navnet på temaet.

/{navn}
Hovedmappe til dit tema
/{navn}/components
Mappe med komponenter til Page Builder
/{navn}/components/sections.json
Liste over hvilke sections der må indsættes på hvilke sider
/{navn}/components/tags.json
Tags til brug i temaet
/{navn}/components/sections
Mappe til de enkelte sections-filer
/{navn}/extensions
Udvidelser til Shoporamas indbyggede datatyper.
/{navn}/templates
Mappe til templates
/{navn}/templates/mails
Mappe til mail-templates

Det er som udgangspunkt frit hvordan filerne i /{navn}/templates navngives. Dog med nogle få undtagelser:

/{navn}/templates/global.html

Den overordnede side der indeholder strukturen for hele shoppen. Selve indholdet indsættes der hvor denne template viser <{$contents}>, som er en speciel variabel der kommer fra nedenstående index.html. Dvs. en meget simpel global.html kunne se sådan ud:

<!DOCTYPE html>
<html>
<head>
	<title><{$webshop->getName()|escape}></title>
</head>

<body>

	<nav>
		<!-- Din navigation -->
	</nav>

	<div>
		<{$contents}>
	</div>

</body>

</html>

/{navn}/templates/index.html

Denne template bruges til at vise indholdet af hvad-end-man-nu-ser. Dvs. et produkt, en landingsside, eller kurven m.m. Et forslag til hvordan den kan se ud er følgende:

<{if $inc}>

	<{include file=$inc}>

<{elseif $category}>

	<{include file="category.html"}>

<{elseif $landing_page}>

	<{include file="landing_page.html"}>

<{elseif $product}>

	<{include file="product.html"}>

<{elseif $page}>

	<{include file="page.html"}>

<{elseif $blog_post}>

	<{include file="blog_post.html"}>

<{/if}>

/{navn}/templates/printed_invoice.html

Bruges fra admin hvis man ønsker at printe en følgeseddel. Indholdet af ordren vil altid ligge i variablen $order.

/{navn}/templates/mails

Mappe til mail-templates. Skal indeholde følgende filer:
after_purchase.html

Hvis du ønsker at sende dine kunder en mail noget tid efter de har handlet.

Relevante variabler: $products $order
basket_mail.html

Mail der automatisk kan sendes hvis kunden har indtastet sin mail-adresse, men ikke checket ud.

Relevante variabler: $basket_url $basket
in_stock_mail.html

Mail der kan sendes hvis en vare kommer på lager igen, og kunden har skrevet sig op.

Relevante variabler: $product
invoice_dropshipping.html

Mail til dropshipping-leverandør.

Relevante variabler: $products $order
invoice.html

Fakturaen for ordren.

Relevante variabler: $order
order_credit.html

Mail hvis ordren krediteres.

Relevante variabler: $order
order_sent.html

Mail der sendes når ordren afsendes.

Relevante variabler: $order
payment_mail.html

Hvis kunden har gennemført en bestilling, men ikke gennemført betalingen.

Relevante variabler: $payment_url $order
product_review_mail.html

Mail der kan sendes til kunden hvis man ønsker anmeldelser.

Relevante variabler: $order
user-reset-password-mail.html

Mail med link til nulstil password. For at få URL'en skal der bruges $customer->getTokenUrl().

Relevante variabler: $customer
user-welcome-mail.html

Velkomst-mail hvis kunden opretter en konto i shoppen.

Relevante variabler: $customer
user-points-expires-mail.html

Mail der sendes til kunden hvis pointene udløber.

Relevante variabler: $customer $points_to_expire $points_expire_date
return_received.html

Mail der sendes til kunden når vedkommende opretter en returnering via returcenteret.

Relevante variabler: $order_return
return_label.html

Mail der sendes til kunden når vedkommende opretter en returnering via returcenteret.

Relevante variabler: $order

Generelt om strukturen i mail-templates

Som udgangspunkt opdeles alle mail-templates i to dele. Den ene del til emnet og den anden del til indholdet. Måden templaten inddelen er ved at checke om variablen $subject er sat. Hvis den er, skal templaten returnerer emnet. Ellers skal den returnere indholdet. Eks.:

<{if $subject}>

	Emnet på mailen

<{else}>

	Indholdet af mailen

<{/if}>

Dog med undtagelse af de to mails invoice.html og invoice_dropshipping.html hvor emnet styres via admin admin og ikke via templaten.

Billeder, stylesheets, m.m. i temaet

Du må lægge dine billeder, og stylesheets, m.m. hvor du ønsker, men vi anbefaler at du fx bruger en struktur som /{navn}/images og /{navn}/css. Når du henviser til filerne skal du bruge variablen $theme_url der indeholder URL'en til temaet. Bemærk at den kan ændre sig, så du kan ikke altid skrive URL'en manuelt ind i dit tema. Men variablen vil altid virke. Hvis du vil linke til billedet /{navn}/images/img.gif skal du derfor skrive .

Udvidelser

Shoporama indeholder nogle forskellige datatyper. Fx produkter og kategorier. De datatyper indeholder nogle foruddefinerede felter som fx titel, beskrivelse, og pris. Det er muligt at udvide de mest almindelige datatyper med sine egne felter. Udvidelser skal placeres i temaet i filen /{navn}/extensions/{datatype}.json, hvor de mulige datatyper er product, landing_page, category, static_page, og blog_post.

Json-filen skal indeholde et array af grupper, hvor hver gruppe indeholder en række felter. Formatet er følgende:

name string

Navnet på gruppen af felter

description string

Længere beskrivelse

fields array

Array af felter

Felt properties:

title

Titlen på feltet

description

Længere beskrivelse hvis relevant

id

ID til at hente værdien ud med

type

En af følgende typer:

multi list text richtext longtext number bool image images color date datetime
options

Værdier hvis type er enten list eller multi. Formatet er

"options": {
	"foo": "Foo",
	"bar": "Bar",
	"baz": "Baz"
}
placeholder

Evt. placeholder

default

Default værdi

Nedenstående er et eksempel på json i filen extensions/product.json:

[
	{
		"name": "Billeder",
		"description": "Her kan du tilføje billeder",
		"fields": [
			{
				"title": "Et enkelt billede",
				"id": "my-image",
				"type": "image"
			},
			{
				"title": "En serie af billeder",
				"id": "my-images",
				"type": "images"
			}
		]
	},
	{
		"name": "Indstillinger",
		"description": "Herunder kan du indstille diverse",
		"fields": [
			{
				"title": "my-setting",
				"description": "Vælg flere ..",
				"id": "tags",
				"type": "multi",
				"options": {
					"foo": "Foo",
					"bar": "Bar",
					"baz": "Baz"
				}
			}
		]
	}
]

Giver følgende interface:

Extension form example

På de datatyper der understøtter udvidelser skal værdierne hentes ud via metoden getExtensionValue('ID'), hvor ID er ID'et fra json-filen. Afhængig af datatypen på feltet kan indholdet returneres som en tekst, array, eller objekt. Eks.:

Materiale: <{$product->getExtensionValue('materiale')}>

Eller:

<{if $img = $product->getExtensionValue('img')}>
	<{$img->getSrc(50, 50, 'fit')}>
<{/if}>

Eller hvis man vil loope billeder igennem:

<{foreach $product->getExtensionValue('my-images') as $image}>
	<img src="<{$image->getSrc(50, 50, 'box')}>">
<{/foreach}>

For date og datetime felter kan værdien bruges direkte eller formateres med Smarty's date_format:

<{* Date felt - vis kun dato *}>
Lanceringsdato: <{$product->getExtensionValue('publishdate')|date_format:'%d/%m/%Y'}>

<{* Datetime felt - vis dato og tid *}>
Publiceringsdato: <{$product->getExtensionValue('publishdatetime')|date_format:'%d/%m/%Y kl. %H:%M'}>

<{* Tjek om produktet skal vises baseret på dato *}>
<{if $launch_date = $product->getExtensionValue('publishdate')}>
	<{if $launch_date|strtotime <= $smarty.now}>
		<!-- Produktet er lanceret -->
	<{/if}>
<{/if}>

<{* Sammenlign datoer *}>
<{if $product->getExtensionValue('publishdatetime')|strtotime > $smarty.now}>
	Kommer snart: <{$product->getExtensionValue('publishdatetime')|date_format:'%d. %B %Y'}>
<{/if}>

Globale variabler

$webshop

Generelt objekt der indeholder webshoppen, men indeholder også en del funktioner til at trække diverse data ud af shoppen. Læs mere om Webshop objektet. Eksempel på hvordan $webshop bruges til at trække en liste over kategorier:

<{foreach $webshop->getCategories() as $category}>
	<{$category->getName()|escape}>
<{/foreach}>
$product

Produkt-objektet hvis du ser en produktside

$category

Kategori-objektet hvis der vises en kategori

$landing_page

Landingsside-objektet hvis du er inde på en landingsside

$page

Objektet til den statiske side hvis du er inde på sådan en

$blog_post

Bloginglægs-objektet hvis du ser et blogindlæg

$inc

Navnet på den specielle - ikke dynamiske, side der afvikles. Værdierne til denne kan være return.html, order-return.html, return_received.html, return_label.html, also.html, search.html, basket.html, address.html, shipping.html, approve.html, payment.html, thanks.html, order.html, product_review.html, subscription.html, blog.html, user-sign-up.html, user-sign-in.html, user-sign-out.html, user-edit.html, user-reset-password.html, user-profile.html, user-orders.html, user-points.html, user-subscriptions.html, user-change-card.html, 404.html, 410.html.

Da vi validerer indholdet kan du med fordel bruge nedenstående kode, og på den måde styre visningen i en include-fil:

<{if $inc}>
	<{include file=$inc}>
<{/if}>
$shipping

Den valgte fragtmetode

$pager_array

Pager hvis den aktelle siden indeholder sidebladring. Indholdet af array'et er elementerne max, current, total, url, og first_url.

$pager

Pager-objekt.

$current_url

Den absolutte URL på den aktuelle side.

$top_url

Relativ URL til den aktuelle side.

$get

Et array med alle GET-variabler.

$post

Et array med alle POST-variabler.

$cookie

Et array med alle COOKIE-variabler.

$user_id

ID'et på shopejeren der er logget ind i admin. Denne variabel sættes hvis man følger et link til shoppen fra admin.

$customer

Customer-objekt hvis kunden er logget ind i shoppen.

$remote_addr

IP-adressen på kunden der ser siden.

$admin_url

URL til Shoporama-admin

$selected_payment_gateway

ID'et på den valgte betalingsgateway.

$join_mailinglist

En indikator om kunden har markeret at denne vil tilmeldes nyhedsbrev.

$basket_url

URL til kurven og dens indhold.

$products_matches

ID'er på produkter der har matchet en rabat eller kampagne

$campaign_ids

ID'er på kampagner hvis produkterne i kurven matcher en kampagne.

$campaigns

Hvis der er en aktive kampagner.

$campaign_discount

Rabatten fra de aktive kampagner.

$campaign_matches

Et array af produkter der matcher en kampagne. Hvis der ikke er nogen produkter er variablen null.

$unpaid_order

Hvis kunden har en ubetalt ordre.

$unpaid_recurring_order

Ubetalt abonnement.

$basket

kurvens indhold som et array, hvor de enkelte elementer er produkterne i kurven, med værdierne:

.id

unikt id på linjen

.product_id

id'et på produktet

.in_stock

true/false om produktet er på lager

.product

produktet

.attributes

produktets attributter

.own_id

sku-nummeret

.amount

antallet i kurven

.comment

evt. kommentar

.bundle

array af produktet hvis produktet er en samlepakke

Eksempel på hvordan ovenstående bruges:

<{foreach $basket as $row}>
	<{if $image = $row.product->getImage()}>
		<img src="<{$image->getSrc(50, 50, 'box')|escape}>">
	<{/if}>

	<{$row.amount}> x <{$row.product->getName()|escape}>

	i alt

	<{$row.product->getRealPrice($row.amount, $row.attributes)|number_format:2:",":"."}>
	<{$webshop->getCurrency()}>

<{/foreach}>

Kig i Template API'et for at se hvilke metoder der er tilgængelig på de forskellige objekter.

$subscriptions

Kurvens abonnementer. Fungerer på samme måde som $basket

$price

Subtotalen på kurvens indhold. Dvs. uden fragt.

$shipping_price

Fragtprisen på kurven.

$total_price

Samlet pris på kurvens indhold.

$vat

Momsen på kurvens indhold.

$basket_weight

Kurvens samlede vægt (til fx fragt).

$total_amount

Kurvens samlede antal produkter.

$voucher

Rabatkoden hvis der er en.

$voucher_discount

Rabatten fra rabatkoden.

$shipping_country

Det valgte leveringsland.

$nofollow

Angiver om nofollow er sat på siden.

$meta_title

Titlen på siden.

$meta_description

Beskrivelse af siden.

$canonical

URL til sidens canonical.

$session_order

Array med faktureringsadressen. Indeholder felterne name, company_name, vat_number, address, address2, zipcode, city, email, phone, ean_number, comments

$session_del

Array med leveringsadressen. Indeholder felterne: name, company_name, address, address2, zipcode, city

$session_extra

Array med ekstrafelter på ordren. Hvis der POST'es et felt med extra[test]=123 vil $session_extra.test være 123, og den gemmes på ordren.

$use_points

Antal point kunden har indtastet de vil bruge på ordren.

$point_discount

Hvor mange DKK (eller anden valuta) de brugte point (fra $use_points) svarer til.

$earns

Hvor mange point kunden optjener ved at gennemføre ordren.

Template-funktioner

Nedenstående er de Shoporama-specifikke funktioner der kan anvendes i templates:

t

Template-sprogsupport

Det er muligt at indbygge sprogsupport i dine templates. Dog ikke klassisk sprogsupport, hvor man kan vælge teksten på flere sprog, men sprogsupport, hvor det er muligt at ændre teksten i admin. Det fungerer ved at pakker teksten ind i en <{t}>-blok. Efter templaten er blevet renderet i browseren kan teksten efterfølgende redigeres i admin. Eks.:

<{t}>Din kurv<{/t}>

Bemærk at hvis du ændrer teksten i dine template-filer, så vil den nye tekst optræde i admin som en ny tekst. Der er ikke nogle ID'er eller navne, ud over indholdet, det gør teksten unik.

Du kan sætte attributten section på blokken for at inddele dine tekster i mere overskuelige dele. Samt hint hvis du vil give et hint i admin når teksten redigeres:

<{t section="basket" hint="Bruger i overskriften"}>Din kurv<{/t}>

Hvis du har variabelt indhold som du vil sende med, uden at værdien kommer i admin, kan du bruge nedenstående syntaks:

<{t amount=$total_amount price=$total_price|number_format:2:",":"." hint="Til kurven"}>
    Du har {amount} ting til {price} kroner i kurven.
<{/t}>

Hvis det passer bedre ind i din struktur kan du også bruge t som en modifier på dine variabler/funktioner:

<{$title = "Min titel her"}>
<{$title|t}>

Ovenstående vil vise følgende i admin:

Smarty translation example
Argumenter
section

Sektion til inddeling i admin

hint

Hint der bruges i admin som hjælpetekst

cache

Template-caching

Hvis en template indeholder en masse tunge kald der ikke behøver være live-opdateret - som fx varianter på produkter, menu, eller kategorioversigt, så indeholder Shoporama en caching-funktion der kan gøre shoppen en del hurtigere. Funktionerne der bruges er hhv. cache og get_cache. Der først markerer den del der skal caches, og senere henter det cachede data ud. Eks.:

<{get_cache name="my_cache" ttl=3600 assign="c"}>

<{if $c}>

	Fra cache: <{$c}>

<{else}>

	Live:

	<{cache name="my_cache"}>
		<{$smarty.now}>
	<{/cache}>

<{/if}>

Funktionen cache pakker indholdet ind og tildeler det navnet som angives i name. Når indholdet skal trækkes ud bruges der get_cache der tager argumenterne name, som brugt tidligere, og ttl som angiver i sekunder hvor gammelt indholdet må være. Hvis argumentet undlades er default én time.

Argumenter
name

Bruges til at angive navnet på det cachede element. Det er muligt at bruge dynamiske navne fra variabler.

get_cache

Cache-indhold hentning

Funktion der returnerer det cachede indhold fra cache-funktionen.

Argumenter
name

Navnet på det cachede element som brugt i cache.

ttl

Time To Live. Antal sekunder som cachen må være gyldig i.

assign

Navnet på den variaben som indholdet skal assignes til.

Tema-indstillinger

Det er muligt at tilføje nogle generelle indstillinger til temaer ved at tilføje en theme_settings.json i roden af temaet, og fremprovokere noget lignende nedenstående:

Theme settings example

Strukturen er følgende:

info

Navnet på temaet

string

features

Array af features temaet indeholder. Bruges kun til visning i admin. Kun brugbart hvis temaet er generelt og flere brugere kan vælge det. Fx ["Feature A", "Feature B", "Feature C"]

array

demo

URL til evt. demoside

string

settings

Array af felter der kan redigeres:

array
.path

ID på felter der indgår i variablen, som første element, når værdien hentes ud. Hvis path sættes til design vil værdierne ligge i $settings.design.{feltnavn}

string
.name

Navn der vises i admin

string
.description

Beskrivelse der vises i admin

string
.fields

De enkelte felter der kan redigeres af brugeren

array
.path

ID'et til når værdien skal hentes ud. Hvis path sættes til color og det overliggende felt var design, kan feltet hentes ud via $settings.design.color

string
.name

Navn der vises i admin

string
.description

Beskrivelse der vises i admin

string
.default

Standardværdi. Hvis feltet er tomt vil denne værdi blive brugt.

string
.type

Typen af feltet. De gyldige typer er: image, color, string, bool, wysiwyg, og list.

string
.values

Værdier hvis type er sat til list. Formater er følgende:

[
	{
		"name": "cheese",
		"value": "Ost"
	},
	{
		"name": "ham",
		"value": "Skinke"
	}
]
array

Eksempel på indhold af fil

{
	"info": "Mit tema",
	"settings": [
		{
			"path": "design",
			"name": "Design",
			"description": "Indstillinger for dit design",
			"fields": [
				{
					"path": "logo",
					"name": "Toplogo",
					"description": "Upload dit logo her",
					"type": "image"
				},
				{
					"path": "background_color",
					"name": "Baggrundsfarve",
					"description": "Baggrundsfarven på shoppen",
					"type": "color"
				},
				{
					"path": "size",
					"name": "Bredde",
					"description": "Bredden på siden",
					"type": "list",
					"values": [
						{
							"name": "Afgrænset",
							"value": "boxed"
						},
						{
							"name": "Fuld bredde",
							"value": "fullwidth"
						}
					]
				}
			]
		},
		{
			"path": "contact",
			"name": "Kontaktoplysninger",
			"description": "Dine kontaktoplysninger der vises i temaet",
			"fields": [
				{
					"path": "mail",
					"name": "E-mail-adresse",
					"description": "Indtast din e-mail-adresse her",
					"type": "string"
				}
			]
		},
	]
}

Page Builder

Page Builderen er et værktøj til at opbygge indhold via sektioner udfra JSON-filer. Disse sektioner kan placeret på forskellige sider i webshoppen. Hvilke sider de kan placeres i defineres i filen /{navn}/components/sections.json. Indholdet af de enkelte sektioner defineres i hver sin egen fil, der placeres i /{navn}/components/sections/{sektion}.json.

Hvis man har gjort ovenstående vil Design linket i toppen af admin automatisk lede til Page Builderen:

Page builder example

Strukturen i opbygningen af sektioner er som følgende:

/{navn}/components/sections.json

Fil: sections.json

Indeholder en liste over sidetyper samt et array af hvilke sektioner der er tilladt. Ud over sidetyper kan man også bruge egne tags.

{
	"Sidetype": ["sektionA", "sektionB"]
}

Der findes følgende sidetype:

product

Produktsider

category

Kategorisider

landing_page

Landingssider

static_page

Statiske sider

blog_post

Blogindlæg

basket

Kurven

address

Adressesiden

shipping

Fragtsiden

approve

Godkendelsessiden

thanks

Takkesiden, som kunden typisk ser efter ordren er gennemført

search

Søgesiden

also

Mersalgssiden, der kan bruges hvis man viser en opsalgsside efter kunden har lagt produkter i kurven

order

Ordresiden, der viser ordrens indhold via et link

#tags

Valgfrie tags du selv opretter

Et eksempel på en sections.json, hvor brugeren må tilføje sektionerne slider, photos, og quiz til landingssider, men kun slider til produktsider, og på #footer må der indsættes en about sektion vil se sådan ud:

{
	"landing_page": ["slider", "photos", "quiz"],
	"product":      ["slider"],
	"#footer":      ["about"]
}
/{navn}/components/tags.json

Fil: tags.json

Tags bruges til lokationer som man selv opfinder, og som man kan trække ud som det passer en. Det kan være at man har brug for en #footer som man trækker ud og viser nederst på shoppen, eller en #xmas opsætning man kun bruger i december. Formatet for tags.json er:
{
	"tag1": "Beskrivelse ...",
	"tag2": "Beskrivelse ...",
	"tag3": "Beskrivelse ..."
}

De enkelte tags dukker automatisk op i admin når brugeren opretter en ny opsætning:

Tags example

For at trække indholdet af tags ud i temaet bruges funktionen getBlocks() på følgende måde:

<{if $blocks = $webshop->getBlocks("#foo")}>
	<{foreach $blocks as $block=>$elements}>
		[...]
	<{/foreach}>
<{/if}>
/{navn}/components/sections

Bibliotek: sections

I dette bibliotek placeres de enkelte sektioner i hver deres json-fil. Hver fil er navngivet efter navnet på sektionen. Hvis sektionen hedder slider skal indholdet ligge i /{navn}/components/sections/slider.json. Strukturen for filerne er følgende
title

Felt: title

Navnet der vises i admin

string
description

Felt: description

Beskrivelse der vises i admin

string
fields

Felt: fields

Et array af felter

array
Egenskaber for array-elementer:
.id

ID'et på feltet. Bruges når indholdet loopes igennem i temaet

string
.type

Indholdets type. Gyldige typer er: list, text, integer, image, images, bool, richtext, longtext, repeater, product, category, og landing_page

string
.options

Bruges kun til felter af typen list, og den indeholder en serie af valgmuligheder som fx:

[...]
"options": {
	"hat": "Hat",
	"glasses": "Briller",
	"beard": "Skæg"
},
[...]
string
.title

Titlen på feltet

string
.description

Beskrivelse af feltet

string
.max

Maksimum felter der kan tilføjes

int
.required

Om feltet er påkrævet

bool
.placeholder

Placeholder til admin

string
.default

Evt. default-værdi til feltet

string
.fields

Bruges kun hvis typen er repeater, og kan indeholde samme felter som sektioner. Et simplificeret eksempel på en slider-repeater kan være:

[...]
"type": "repeater",
"fields": [
	{
		"id": "headline",
		"type": "text",
		"title": "Overskrift"
	},
	{
		"id": "img",
		"type": "image",
		"title": "Billedet"
	}
]
[...]
string
.field_title

Bruges kun hvis typen er repeater, og indeholder navnet på de enkelte elementer i repeateren

string

Visninger

Der er forskellige strategier for at trække data ud. Som udgangspunkt vil der være en $page_blocks på de sider der matcher en opsætning. Den kan loopes den igennem, eller indholdet kan trækkes ud via $webshop->getBlocks('#foo'). Eller indholdet kan tilgås via navnet på sektionen.

Som udgangspunkt vil vi anbefale at man placerer visningen af de enkelte sektioner i separate filer, som fx /{navn}/templates/sections/{section}.html. Derefter er det nemt at loope $page_blocks igennem og inkludere den rigtige visning på følgende måde:

<{if $page_blocks}>

	<{foreach $page_blocks as $section}>
		<{$type = $section._type}>

		<{if $webshop->templateExists("sections/$type.html")}>

			<{include file="sections/$type.html"}>

		<{/if}>

	<{/foreach}>

<{/if}>

Bemærk at rækkens type ligger i variablen _type.

Nedenstående sektion kalder vi images - indholdet ligger derfor i /{navn}/components/sections/images.json.

{
	"title": "Overskrift og billeder",
	"fields": [
		{
			"id": "headline",
			"type": "text",
			"title": "Overskrift"
		},
		{
			"id": "images",
			"type": "images",
			"title": "Billeder"
		}
	]
}

Det giver følgende interface i admin:

Images example

For at trække indholdet ud via ovenstående metode kan /{navn}/templates/sections/images.html indeholde følgende:

<h1><{$section.headline|escape}></h1>

<{foreach $section.images as $image}>
	<img src="<{$image->getSrc(150, 150, 'box')}>">
<{/foreach}>

Mht. datatype er det vigtigt at være opmærksom på hvad de enkelte felter indeholder. De kan være enten string, array, eller object. Dvs. man bør gøre noget lignende:

[...]
<{foreach $section as $name=>$val}>
	<{if is_array($val)}>
		Repeater eller array af billeder
	<{elseif is_object($val)}>
		Et billede
	<{else}>
		Tekst, tal, eller lignende
	<{/if}>
<{/foreach}>
[...]

Bruger man typerne product, category, eller landing_page returneres der det valgte ID i temaet, og man skal selv trække objektet ud med metoderne $webshop->getProductById(id), $webshop->getCategory(id), eller $webshop->getLandingPage(id). Fx:

[...]
<{if $product = $webshop->getProductById($section.product_id)}>
	<{$product->getName()|escape}>
<{/if}>
[...]

Bemærk at det altid er muligt at bruge var_dump for at undersøge hvad variablen indeholder, og på den måde loope den korrekt igennem.

Visninger

Med udgangspunkt i tidligere nævnt struktur gennemgås herunder de enkelte visninger. For at forstå de enkelte objekter, og hvilke metoder der er tilgængelige anbefaler vi at kigge i vores Template API.

Download vores Alaska-tema for at se eksempler på de forskellige visninger.

Produkter

Visningen at produkter kan ligge i product.html, men det er valgfrit. Det er altid index.html der afvikler de enkelte visninger. Men vi anbefaler at man bruger denne struktur. For at vide at der afvikles en produktvisning checkes der om $product er til stede.

Læg i kurv

Produkter tilføjes til kurven ved at lave et POST kald til en vilkårlig side - typisk bare den side man allerede viser, med argumenterne product_id, attributes[{attribut_id}]={attribut_value_id}, og amount. Attributten skal kun tilføjes hvis produkter har varianter.

Et simpelt eksempel på hvordan man lægger produkter i kurven kan være:

<form action="" method="post">
	<input type="hidden" name="product_id" value="<{$product->getProductId()}>"/>
	<input type="number" name="amount" value="1" min="1"/>
	<input type="submit" value="Læg i kurv">
</form>

Med varianter:

<form action="" method="post">
	<input type="hidden" name="product_id" value="<{$product->getProductId()}>"/>

	<{foreach $product->getProfile()->getAttributeList() as $attribute}>
		<{if $attribute->getIsVariant() && $attribute->getDataType() == "valuelist"}>
			<select name="attributes[<{$attribute->getAttributeId()}>]">
				<{foreach $attribute->getValues() as $value}>
					<option value="<{$value->getAttributeValueId()}>">
						<{$attribute->getName()|escape}>: <{$value->getVal()|escape}>
					</option>
				<{/foreach}>
			</select>
		<{/if}>
	<{/foreach}>

	<input type="number" name="amount" value="1" min="1"/>
	<input type="submit" value="Læg i kurv">
</form>

Ovenstående kan selvfølgelig gøres mere kompliceret hvis man ønsker at vise lagerstatus, samlepakker, m.m.

Landingssider

Landingssider indeholder en $landingpage samt $products som er et array af produkter der skal vises på siden.

Hvis siden kræver en pager indsættes den på følgende måde:

<{if $pager}>
	<{$pager->render()}>
<{/if}>

Kategorier

Kategorier indeholder en $category samt $products som er et array af produkter der skal vises på siden.

Hvis siden kræver en pager indsættes den på følgende måde:

<{if $pager}>
	<{$pager->render()}>
<{/if}>

Statiske sider

Statiske sider vil indeholde en $page.

Blog

Bloggen kan inddeles i to sider: blog.html og blog_post.html, hvor første kan trække en liste over blogindlæg via:

<{$blog_posts = $webshop->getBlogPosts()}>

Selve visningen af de enkelte blogindlæg foregår ved at kigge på variablen $blog_post.

Hvis listen over blogindlæg kommer fra en kategori er der også en $category tilstede med den pågældende kategori.

Produktanmeldelser

I product_review.html er der adgang til $order, og som er ens ordre. Man kan kun anmelde produkter man har købt. Ud fra ordren kan man trække produkterne via $order->getOrderProducts(). For at gemme produktanmeldelserne skal man lave et POST kald til samme side med følgende indhold:

<{if $order}>
	<{if $get.voted}>
		Tak!
	<{else}>
		<form action="" method="post">
			<{foreach $order->getOrderProducts() as $product}>
				<{$product->getName()|escape}>
				Stjerner:
				<input type="number" min="1" max="5" name="rating[<{$product->getProductId()}>]">
				Anmeldelse
				<textarea name="description[<{$product->getProductId()}>]"></textarea>
			<{/foreach}>
			<input type="submit" value="Skriv anmeldelse"/>
		</form>
	<{/if}>
<{/if}>

$get.voted er true når kunden har anmeldt.

For at linke til anmeldelsessiden fra din ordre skal du bruge $order->getReviewUrl().

Søgningen fungerer ved at lave et GET kald til /search hvor argumentet ?search= skal være ens søgeord. Eks.:

<form action="/search">
	<input type="text" name="search" value="<{$get.search|escape}>"/>
	<input type="submit" value="Søg"/>
</form>

Der søges i både produkter, kategorier, blogindlæg, og landingssider. For at vise resultatet skal der derfor kigges på de fire variabler $products, $categories, $blog_posts, $pages, og $landing_pages.

Om der søges i statiske sider skal aktiveres i admin.

Ønskeliste

Hvis dine kunder kan logge ind på din shop, kan du give dem mulighed for at oprette ønskelister. De kan oprette alle de ønskelister de ønsker, og en ønskeliste har et navn, en beskrivelse, og en række produkter. Selve ønskelisten har en offentlig adresse så dine kunder kan sende et link.

Ønskelisten bruger følgende templates:

wishlist.html
URL: /wishlist

Siden med den offentlige ønskeliste.

Relevante variabler:

$wishlist der indeholder ønskelisten. Se metoder her.

user-wishlists.html
URL: /user-wishlists

Siden med brugerens ønskelister. Kræver login.

Relevante variabler:

$customer->getWishlists() til at trække ønskelister ud.

user-wishlist.html
URL: /user-wishlist

Siden der bruges til at redigere ønskelisten samt produkter

Relevante variabler:

$wishlist der indeholder ønskelisten. Se metoder her.

For at oprette en ønskeliste skal der fra user-wishlists.html sendes en POST med feltet name, og en valgfrit description. Fx

<form action="" method="post">
    Navn
    <input type="text" name="name">

    Beskrivelse
    <textarea name="description"></textarea>

    <input type="submit" value="Opret">
</form>

Bemærk at du med fordel kan bruge metoderne $wishlist->getRemoteUrl() og $wishlist->getEditUrl() til at lave links til visning og redigering af ønskelisterne.

I filen user-wishlist.html hvor ønskelisten redigeres, skal navnet og beskrivelsen sendes som name, description, og status der kan være enten active eller closed. Selve produkterne, og deres antal, og evt. kommentar skal sendes som et array i følgende format:

wishlist_product[{id}][name] = 'navn'
wishlist_product[{id}][comments] = 'kommentar'
wishlist_product[{id}][remove] = '1' // kun hvis produktet skal fjernes

Eksempelkode:

<{foreach $wishlist->getWishlistProducts() as $wp}>
    <{* Fordi der er forskel på produkter og ønskelisteprodukter }*>
    <{$product = $wp->getProduct()}>

    <input type="checkbox" name="wishlist_product[<{$wp->getWishlistProductId()}>][remove]" value="1">

    <a href="<{$product->getUrl()|escape}>"><{$product->getName()|escape}></a>

    <{if $variant = $wp->getVariantValue()}>
        <{$wp->getVariantName()|escape}>: <{$variant|escape}>
    <{/if}>

    <input type="number" name="wishlist_product[<{$wp->getWishlistProductId()}>][amount]" value="<{$wp->getAmount()}>">

    <textarea name="wishlist_product[<{$wp->getWishlistProductId()}>][comments]"><{$wp->getComments()|escape}></textarea>

<{/foreach}>

Hvis der sendes en variabel edit vil siden returnerer til samme redigeringsside igen. Ellers sendes der videre til oversigten over ønskelister. For at slette ønskelisten skal der sendes en variabel ved navn remove. Fx.

<input type="submit" name="remove" value="Slet" onclick="return confirm('Er du sikker?');">

For at tilføje produkter til en ønskeliste fra shoppen, kan der fra en vilkårlig side laves et POST-kald med felterne wishlist_id, product_id, og en valgfri attribute_value_id, hvis der er variant på produktet. Eks.:

<{if $product && $customer}>

    <{if $wishlists = $customer->getWishlists()}>

        <form action="" method="post">
            <input type="hidden" name="product_id" value="<{$product->getProductId()}>"/>

            <label>Vælg ønskeliste:</label>
            <select name="wishlist_id">
                <{foreach $wishlists as $wishlist}>
                    <option value="<{$wishlist->getWishlistId()}>">
                        <{$wishlist->getName()|escape}>
                    </option>
                <{/foreach}>
            </select>

            <{if $variant = $product->getVariant()}>
                <label>Vælg variant:</label>

                <select name="attribute_value_id">
                    <{foreach $variant->getValues() as $value}>
                        <option value="<{$value->getAttributeValueId()}>">
                            <{$variant->getName()|escape}>: <{$value->getVal()|escape}>
                        </option>
                    <{/foreach}>
                </select>
            <{/if}>

            <input type="submit" value="Tilføj til ønskeliste">
        </form>

    <{/if}>

<{/if}>

Returcenter

Returcenteret giver dine kunder mulighed for selv at oprette returneringer. Det skal aktiveres under indstillinger for shoppen. Når en kunde har oprettet en returnering skal den godkendes i admin, og der vil blive lavet en kreditnota.

Returcenteret bruger følgende templates:

return.html

Template: return.html

URL: /return

Siden hvor returneringen oprettes

Relevante variabler:

$order der indeholder ordren kunden ønsker at returnere. Se metoder her.

order-return.html

Template: order-return.html

URL: /order-return

Siden hvor returneringen efterfølgende vises

Relevante variabler:

$order_return med returneringen. Se metoder her.

return_received.html

Template: return_received.html

URL: Email template

Mail der sendes til kunden når vedkommende opretter en returnering

Relevante variabler:

$order_return med returneringen. Se metoder her.

Der er to måder at ens kunde kan komme ind på siden med returnering. Den ene er ved at angive ordrenummer og e-mail-adresse på sin ordre. Den anden er ved at følge et direkte link. Det direkte link trækkes ud af ordren ved at bruge $order->getReturnUrl(). Fx

<{if $webshop->useReturnCenter() && !$order->getIsCreditNote()}>
	<a href="<{$order->getReturnUrl()|escape}>">Retuner varer</a>
<{/if}>

Som det ses i eksemplet er det en god idé at kontrollere at ordren ikke er en kreditnota, og om webshoppen har aktiveret returcenteret. Eksemplet kan bruges alle steder hvor der er en $order. Fx kundens egen ordreoversigt, eller i mails.

Hvis man ikke bruger login, eller på anden måde ønsker at kunden kan søge sin ordre frem, skal man på return.html implementere en søgning med ordrenummer og e-mail-adresse. Det er felterne webshop_order_id og email der skal POST'es til /return. Hvis ordren findes bliver kunden sendt videre til returneringen, hvis ikke vil $get.not_found være sat, og man kan vise en fejlbesked i temaet. En minimal formular kan se ud på følgende måde:

<{if $get.not_found}>
    <p>Der blev ikke fundet nogen ordre.</p>
<{/if}>

<h1>Returcenter</h1>

<form method="post" action="">
    <input type="number" name="webshop_order_id" placeholder="Ordrenummer">
    <input type="email" name="email" placeholder="E-mail-adresse">

    <input type="submit" value="Søg">
</form>
Oprettelse af returnering

I filen return.html skal der trækkes en liste af ordrelinjer ud, og kunden kan vælge hvilke produkter der skal returneres, og evt. hvorfor. I modsætning til almindelige ordrevisninger skal returneringen indeholde en linje pr. ordrelinje.

<form action="" method="post">
    <{$line = 0}>

    <!-- Looper ordrelinjerne igennem -->
    <{foreach $order->getOrderProducts() as $product}>

        <!-- getReturned() returnerer antallet der tidligere er returneret -->
        <{$returned = $product->getReturned()}>

        <!-- Løkke for hver antal -->
        <{section name="i" loop=$product->getAmount()}>
            <{$line = $line+1}>

            <!-- Viser ikke flere end det er muligt at returnere -->
            <{if $line - $returned > 0}>

                <{$product->getName()|escape}>

                <{if $attributes = $product->getAttributes()}>
                    <{foreach $attributes as $attribute}>
                        <{$attribute.name}>: <{$attribute.val}>
                    <{/foreach}>
                <{/if}>

                <!-- Check hvilken pris der skal vises -->
                <{if $webshop->getUseCalculatedUnitPrice()}>
                    <{$webshop->getCurrency()}> <{$product->getCalculatedUnitPrice()|number_format:2:",":"."}>
                <{else}>
                    <{$webshop->getCurrency()}> <{$product->getUnitPrice()|number_format:2:",":"."}>
                <{/if}>

                <!-- Checkbox og en grund -->
                <input type="checkbox" name="return[<{$line}>]" value="<{$product->getOrderProductId()}>">Vælg
                <input type="text" name="reason[<{$line}>]" placeholder="Evt. årsag til returnering"/>

            <{/if}>
        <{/section}>

     <{/foreach}>
</form>

Det er muligt i admin at angive fast leveringsmetode og -pris. Hvis dette er gjort trækkes leveringsmetoden ud via $webshop->getReturnShipping($country_id), og hvis prisen er fast, trækkes den ud via $webshop->getReturnShippingPrice($country_id). Fx:

<{if $return_shipping = $webshop->getReturnShipping($order->getDelCountryId())}>
    Varer skal returneres via <{$return_shipping->getName()|escape}>.

    <{if $price = $webshop->getReturnShippingPrice($order->getDelCountryId())}>
        Prisen er <{$price|number_format:2:",":"."}>
    <{else}>
        Prisen er <{$return_shipping->getCost()|number_format:2:",":"."}>
    <{/if}>
<{else}>
    <!-- Vis en liste over shoppens almindelige leveringsmetoder her -->
<{/if}>

Den valgte leveringsmetode, hvis valgfri, skal sendes som shipping_id.

Visning af returnering

Når returneringen er oprettes vises den i order-return.html, der indeholder en $order_return med de relevante metoder.

/also

also.html er vores side til mersalg. Som udgangspunkt er der adgang til $product, og udfra den kan man komme med forslag til kunden. Det kan fx være relevant at bruge $product->getRelatedProducts(), $product->getAlsoBought(), eller $webshop->getPopularProducts().

404

Bruges kun til at vise 404-sider.

410

Bruges kun til at vise 410-sider.

Captcha

Der indsættes automatisk en captcha når man prøver at tilmelde sig nyhedsbrev, eller skrive kommentarer. Dette er for at undgå spam. Det er muligt selv at designe siden i captcha.html, og den skal som minimum indeholde:

<form action="" method="post">
	<{$form}>

	<{if $error}>Fejl i koden<{/if}>

	<img src="<{$imgstr}>">

	Skriv indholdet at ovenstående felt:
	<input type="text" name="c">

	<input type="submit" value="OK">
</form>

Login

Det er muligt at lade ens kunder logge ind i shoppen. Hvis vedkommende er er logget ind vil der være en $customer der indeholder informationer om brugeren. Alle sider der redigerer, logger ind, m.m. skal submitte via POST til siden selv.

/user-edit.html

Bruges til redigering af kundens data. Det er muligt at tilføje felter til kunden. Se mere under denne tabel.

Relevante variabler:
company vat_number name email phone address zipcode city country_id pass1 pass2
/user-orders.html

Kundens tidligere ordrer

Relevante variabler:
$my_orders
/user-points.html

Kundens point

Relevante variabler:
$my_points
/user-profile.html

Visning af kundens data

Relevante variabler:
$customer
/user-reset-password.html

Bruges til nulstilling af password

Relevante variabler:
email password
/user-sign-in.html

Login siden. Brug redir hvis kunden efter login skal sendes videre til en URL.

Relevante variabler:
email password redir
/user-sign-up.html

En formular som kunden bruger til at registrere sig.

Relevante variabler:
name email phone address zipcode city company vat_number country_id

Egne felter til kunden

Det er muligt i admin at definere egne felter til ens brugere. De felter redigeres på følgende måde:

<{foreach $webshop->getCustomerFields() as $field}>
	<{if $field->getType() == "list"}>
		<{$field->getName()|escape}>
		<select name="field[<{$field->getCustomerFieldId()}>]">
			<{foreach $field->getValues() as $value}>
				<option <{if $field->getVal() == $value}>selected="selected"<{/if}> value="<{$value|escape}>">
					<{$value|escape}>
				</option>
			<{/foreach}>
		</select>
	<{elseif $field->getType() == "string"}>
		<{$field->getName()|escape}>
		<input type="text" name="field[<{$field->getCustomerFieldId()}>]" value="<{$field->getVal()|escape}>">
	<{/if}>
<{/foreach}>

Loyalitetsprogram

Loyalitetsprogrammet giver mulighed for at dine kunder kan optjene, og bruge, point når de gennemfører ordrer. Opsætningen styres under Kunder > Loyalitetsprogram.

Du kan bruge nedenstående metoder til at checke om shoppen har aktiveret loyalitetsprogrammet, og om kunden er logget ind, samt har optjent point de kan bruge:

<{if $webshop->hasLoyaltyProgram() && $customer && $customer->getActivePoints()}>
	[Visning af point m.m.]
<{/if}>

For at vise hvor mange point kunden har optjent, samt hvor mange de kan bruge på den aktuelle ordre kan du bruge følgende kodeeksempel:

Du har optjent <{$customer->getActivePoints()|number_format:0:",":"."}> point.

<{if $points = $customer->getPointsAvailable()}>
	Du kan bruge <{$points|number_format:0:",":"."}> point på denne ordre.
<{else}>
	Du har ingen optjente point du kan bruge på denne ordre.
<{/if}>

Det felt du POST'er til kurven, der angiver hvor mange point kunden vil bruge, skal hedde use_points, og kan se ud som følgende:

<input type="number" name="use_points" value="<{$use_points}>" min="0" max="<{$customer->getPointsAvailable()}>"/>

Du kan bruge $earns til at se hvor mange kunden optjener på ordren:

Du optjener <{$earns|number_format:0:",":"."}> point på denne ordre.

Du kan bruge nedenstående eksempel hvis du vil beskrive dit loyalitetsprogram:

Du optjener <{$webshop->getLoyaltyProgramBasePoints()|number_format:0:",":"."}> point hver
gang du køber for 1 <{$webshop->getCurrency()}>. Når du betaler med point svarer
<{$webshop->getLoyaltyProgramBaseCost()|number_format:0:",":"."}> point til 1 <{$webshop->getCurrency()}>.

Hvis du vil lave en side med pointoversigt kan du bruge user-points.html, hvor du kan loope $my_points igennem, og præsentere indholdet. Kig på SafePoint-klassen for at se hvilke metoder der er tilgængelig.

Tip: du kan style din ordreoversigt, ved at bruge følgende CSS-klasser: points_used, points_earned, og has_profile.

Check ud

Check ud flowet er simpelt set en serie af html-sider der hver især indeholder en formular der POST'er noget data til sig selv, og hvis feltet next er sat, vil Shoporama sende videre til næste side i flowet. Typisk vil man sætte "Næste" knappen til name="next". Der kan altid linkes til tidligere sider i flowet. Når kunden har indtastet sine oplysninger ligger disse i to arrays hhv. $session_order og $session_del. Fx $session_order.name.

basket.html

Filnavn: basket.html

Viser kurvens indhold. Simpelt eksempel hvordan $basket bruges:

<{foreach $basket as $line}>
	<{$line.amount}> x <{$line.product->getName()}>

	<{foreach $line.attributes as $a}>
		<{$a.name|escape}>: <{$a.value|escape}>
	<{/foreach}>
<{/foreach}>

For at ændre på antallet skal det POST'es på følgende måde

[...]
<input name="amount[<{$line.id}>]" value="<{$line.amount}>" />
[...]

For at tilføje en rabatkode skal der POST'es en voucher med rabatkoden. Hvis rabatkoden er ugyldig vil $get.wrong_voucher være til stede i templaten.

Leveringslandet kan ændres ved at POST'e en del_country_id med ID'et på leveringslandet.

Relevante variabler/parametre i formularen:
$basket $voucher $voucher_discount $campaign_ids $campaign_discount $price $shipping_price $total_price $vat
address.html

Filnavn: address.html

Siden hvor leveringsoplysningerne indtastes.

Hvis mailinglist sættes til 1 tilmeldes kunden til nyhedsbrev.

Hvis create_profile sættes til 1 oprettes der en profil til kunden så vedkommende efterfølgende kan logge ind.

Relevante variabler/parametre i formularen:
order_country_id order_name order_company_name vat_number ean_number order_address order_zipcode order_city email phone comments del_name del_company_name del_address del_zipcode del_city del_country_id mailinglist create_profile
shipping.html

Filnavn: shipping.html

Bruges til at vælge leveringsmetode.

De enkelte leveringsmetoder kan trækkes ud via $webshop->getShippings().

For at gemme leveringsmetode skal der POST'es en shipping_id med ID'et på den leveringsmetode. Hvis leveringsmetoden har et pakkeshop tilknyttet trækkes de ud via $shipping->getDeliveryShops(). Du kan vælge pakkeshop på følgende måde:

[...]
<{if $shipping->getModule()}>
	<select name="shop">
		<{foreach $shipping->getDeliveryShops() as $shop}>
			<option value="<{$shop.number}>">
				<{$shop.name|escape}>
				<{$shop.street|escape}>
				<{$shop.zip|escape}>
				<{$shop.city|escape}>
			</option>
		<{/foreach}>
	</select>
<{/if}>
[...]
Relevante variabler/parametre i formularen:
shipping_id shop
approve.html

Filnavn: approve.html

Godkendelsessiden. Bruges til at vise ordren.

Hvis shoppen indeholder flere betalingsgateways kan disse vælges på denne side. De hentes ud via $webshop->getPaymentGateways() og submittes via payment_gateway_id for at skifte.

Relevante variabler/parametre i formularen:
$basket $shipping payment_gateway_id
thanks.html

Filnavn: thanks.html

Takkesiden. Bruges til at vise ordren der er gennemført.

Relevante variabler/parametre i formularen:
$order

Ajax

Shoporama har to indbyggede ajax-kald. Det ene kan trække produkter ud på forskellige måder (filtrering), og det andet er en generel og simpel søgning der søger i produkter, kategorier, og landingssider.

Filtrering

Filtreringen ligger i filen /ajax som ligger i roden af alle shops

atags

En liste af tags på attributværdierne, attributværdier er indstillinger på attributterne på produkternes profiler. værdierne på atags skal være adskilt af komme, men tillader grupperinger adskilt af pipe som en logisk OR.

ajax?atags=female,black|white
product_ids

Liste af product_id'er adskilt af pipe.

ajax?product_ids=1|2|3|4
price_range

Returnerer produkter der ligger indenfor et prisområde. Beløbene skal adskilles af pipe.

ajax?price_range=100|200
categories

En pipe-separeret liste af kategorier produkterne skal ligge i. Hvis argumentet exclude=1 sættes returneres der en liste af produkter der ikke har kategorierne.

ajax?categories=5|9|2
ajax?categories=5|9|2&exclude=1
sort

Sorteringsrækkefölgen. Der kan sættes värdierne popular, weight, name, price, created. Om sorteringen skal være faldende eller stigende angives ved at sætte sort_order til enten asc (stigende) eller desc (faldende).

ajax?sort=price&sort_order=desc
attribute_values

En liste af id'er på attributværdierne som produkterne skal have. Listen adskilles af pipe. Hvis argumentet exclude=1 sættes returneres der en liste over produkter der ikke matcher.

ajax?attribute_values=9|8|12
suppliers

Pipe-separeret liste af id'er på leverandörer.

ajax?suppliers=8|2
landing_pages

Pige-sepereret liste af id'er på landingssider produkterne skal optræde på.

ajax?landing_pages=5|24
extension.{id}

Hvis temaet bruger udvidede felter kan der trækkes produkter ud på baggrund af dem. Der laves absolutte søgninger, så de felter der giver mest mening at bruge er bool, multi, number, og list. Der kan bruges pipe-separerede værdier hvis produkterne skal matche bare én af værdierne.

ajax?extension.foo=1&extension.tags=foo|bar
attribute_tags_in_stock

Liste af tags på attributværdier der skal være på lager. Listen kan pipe-separeres.

ajax?attribute_tags_in_stock=foo|bar
attribute_tags

Liste af tags der skal være sat på produkterne. Listen kan pipe-separeres.

ajax?attribute_tags=foo|bar
attribute_tag

Samme som attribute_tags bare kun med et enkelt tag.

ajax?attribute_tag=foo
force_categories

En pipe-separeret liste over kategori-id'er der alle skal være sat på produkterne.

ajax?force_categories=5|9|2
limit

Maks. antal produkter der skal returneres.

ajax?limit=10
offset

Startposition ift. hvor i listen af produkter man önsker at hente fra.

ajax?offset=100&limit=10
meta

Pipe-separeret liste af ekstrafelter man önsker at se på produkterne i resultatet. Hvis man sätter meta=_all returneres alle.

ajax?meta=foo|bar
ajax?meta=_all
only_in_stock_variants

Sættes til 1 eller 0 afhængig af om hvert produkt i resultatet kun skal medtage varianter der er på lager. Default er 0.

ajax?only_in_stock_variants=1
include_meta

Sættes til 1 eller 0 afhængig af om man önske et ekstra meta-felt i resultatet der indeholder beskrivelser af produkterne i resultatet. Det er oplysninger om hvilke attributter, kategorier, og brands der findes. Default er 0.

ajax?include_meta=1
include_pagination

Sættes til 1 eller 0 afhængig af om man önske et ekstra pagination-felt i resultatet der indeholder paging oplysninger. Felterne i array'et er offset, limit, count, total. Default indstilling er 0.

ajax?include_pagination=1
pretty

Sættes til 1 eller 0 afhängig af om json-svaret skal formateres pænt eller ej.

ajax?pretty=1

Svaret fra /ajax er et array i nedenstående format:

[
    {
        "product_id": 139735,
        "own_id": "skunumme",
        "name": "Produktnavn",
        "supplier_id": 0,
        "supplier_name": "",
        "category_ids": [
            3661,
            2113,
            2106,
            1973
        ],
        "category_names": [
            "Bob",
            "Forside",
            "Ged",
            "Giraf"
        ],
        "description": "<p>...</p>",
        "list_description": "",
        "profile_name": "Default m. variant",
        "allow_negative_stock": 1,
        "brand_name": "TESTBRAND",
        "sale_price": 0,
        "real_price": 80,
        "price": 80,
        "price_dk": "80,00",
        "approx_shipping": 0,
        "delivery_time": "",
        "delivery_time_not_in_stock": "",
        "url": "https://example.com/produkt",
        "stock": 0,
        "attr_stock": null,
        "variant_stock": [
            {
                "attribute_id": 2740,
                "attribute_value_id": 16287,
                "name": "S",
                "weight": 10,
                "cnt": 4
            },
            {
                "attribute_id": 2740,
                "attribute_value_id": 16289,
                "name": "L",
                "weight": 30,
                "cnt": 9
            }
        ],
        "stock_string_da": "Nej",
        "avg_rating": null,
        "thumbnail": "https://example.com/cache/1/9/6/9/bob-fit-200x200x90.png",
        "meta_values": [
            null
        ],
        "online_since": 1651685711,
        "has_campaigns": true,
		"campaign_info": [
            {
                "name": "Bob",
                "price_model": "cheapest_free",
                "min_product_count": 4,
                "price": 0,
                "percent": 0,
                "created": "2023-02-01 14:55:47",
                "expires": null
            }
        ]
    }
]

Af hastighedsmæssige årsager cacher vi svaret fra ajax-filen, men i testmiljø kan der tilføjes rebuild=1 som argument for at siden genopbygges. Vi anbefaler at man ikke gør det i produktionsmiljøet, da det kan sløve siden markant.

Siden /ajax_search indeholder en generel søgning til produkter, kategorier, og landingssider. Den kan fx bruges til en autocomplete i ens søgefelt. Den tager følgende argumenter:

term

Søgeordet.

ajax_search?term=ostemad
limit

Maks. antal resultater.

ajax_search?term=ostemad&limit=25
include

En kommasepareret liste af datatyper man ønsker at søge i. Værdierne kan være products, categories, blog_posts, pages, og landing_pages.

ajax_search?term=ostemad&include=products,categories
pretty

Sættes til 1 eller 0 afhængig af om json-svaret skal formateres pænt eller ej.

ajax_search?term=ostemad&pretty=1

Resultatet er et array i nedenstående format:

[
    {
        "name": "Produkt et",
        "supplier": "",
        "description": "<p>...</p>",
        "price": 80,
        "sale_price": null,
        "normal_price": 80,
        "currency": "DKK",
        "price_dk": "80,00",
        "url": "https://example.com/produkt-et",
        "stock": 0,
        "stock_string_da": "Nej",
        "review_avg": 0,
        "thumbnail": "https://example.com/cache/1/9/8/4/box-100x100x90.png",
        "type": "product"
    },
    {
        "name": "Produkt to",
        "supplier": "",
        "description": "<p>...</p>",
        "price": 80,
        "sale_price": null,
        "normal_price": 80,
        "currency": "DKK",
        "price_dk": "80,00",
        "url": "https://example.com/produkt-to",
        "stock": 0,
        "stock_string_da": "Nej",
        "review_avg": 0,
        "thumbnail": "https://example.com/cache/1/9/6/9/bob-box-100x100x90.png",
        "type": "product"
    }
]