Subsections
11.3 Mallarnas syntax

Kodexempel kan för närvarande se märkligt ut i html-verionen av manualen. Vänligen läs nästkommande
stycken i pdf-manualen
Det finns många olika sätt att bygga interaktiva webbtjänster på,
tyvärr så har de flesta mer än sin beskärda del av problem. Några av
de vanligaste problemen man stöter på är: mediokra
programmeringsspråk, omständliga att använda, inte flexibla nog,
alltför plattformsberoende, inte skalbara, begränsade möjligheter till
att göra vad man vill. Efter att ha prövat på ett flertal av de
lösningar som finns på marknaden så kunde vi bara konstatera att
Det här kan göras bättre!
Denna insikt var fröet till den programvara som nu finns bakom Svenska
Butiker. Den är byggd utifrån följande enkla föresatser:
- Form och design skilda från kod.
- Den som utvecklar
funktionalitet brukar inte vara samma person som skapar
designen av sidorna. Designern skall bara behöva veta vad
han/hon vill göra, inte hur det skall göras. Det skall gå att
skapa sidor i en grafisk editor. Om man lägger programkod i
sidorna och sedan låter en icke programmeringskunnig designer
ta hand om dem kan det bara gå illa. Finns inte en önskad
funktion i systemet redan får den utvecklas av programmeraren.
- Full frihet att välja design.
- Systemet får inte begränsa
sidornas utseende eller inbördes struktur. Detta gör att
systemet inte skall känna till vilka sidor som finns i den
aktuella applikationen
- Kod skall så långt det går kunna återanvändas.
- Det säger sig
självt att kod som skrivs i en HTML-sida bara kan återanvändas
genom kopiering, hur bra det fungerar i längden veta alla som
har någon erfarenhet av programmering.
- Lätt att bygga ut med nya funktioner.
- Stommen i systemet
skall tillhandahålla ett antal grundläggande funktioner, allt
annat kund/applikations-specifikt skall kunna läggas till i
plug-in-moduler.
- Skalbart och plattformsoberoende.
- Systemet skall bygga på
komponenter som går att flytta till andra plattformar om behov
skulle uppstå.
Med dessa enkla föresatser som bakgrund är sedan systemet uppbyggt i
en väl genomtänkt flexibel struktur med en databas och HTML-sidor samt
kod som binder dessa samman.
För att hålla reda på vad som skall visas, dvs vilket tillstånd/läge
som användaren befinner sig i har systemet en stackliknande
minnesfunktion. Denna stack kan liknas vid ett höghus med många
våningar och flera lägenheter på varje våning. Man ger varje våning
ett våningsnamn och man ser sedan till att det på varje våning inte
bor två personer med samma namn. Man kan nu identifiera en specifik
lägenhet genom att ange
Våning.Namn. Om man nu vill ha tag i en
Pettersson och man inte vet vilken våning han bor på, får man
kontrollera varje våning för sig tills man hittar honom. Detta kan man
göra på två olika sätt, genom att börja på den lägsta våningen och
vandra uppåt, eller genom att börja på den översta och fortsätta
neråt. Om det finns mer än en Pettersson i huset så kommer man att
hitta olika personer beroende på vilken metod man använder. Vi utökar
modellen genom att kunna bygga en ny våning överst i huset för nya
personer att flytta in, samt att kunna ta bort en våning och alla över
denna från huset.
Table 11.1:
Information som finns på stacken innan en sida bearbetas.
| Taggnamn |
Nivå |
Beskrivning av innehåll |
Skrivning möjlig |
| YYY |
n+1 |
Resultat från FETCH YYY kommando i HTML sida |
NEJ |
| XXX |
n |
Resultat från FETCH XXX kommando i HTML sida |
NEJ |
| Cart |
8 |
Statusinfo om kundvagnen |
NEJ |
| Data |
7 |
Data som skickats via POST eller GET i requesten. Värden
från POST slår ut samma värde från GET (kan vara tomt) |
JA |
| Session |
6 |
Data i den nuvarande sessionen. (kan vara tomt) |
JA |
| Customer |
5 |
Information om aktuell kund (om sådan finns). |
NEJ |
| Cookie |
4 |
Alla cookies som skickats. |
NEJ |
| Shop |
3 |
Butikens inställningar. |
NEJ |
| System |
2 |
Systeminställningar. |
NEJ |
| ENV |
1 |
Alla environment variabler som ett CGI program har
tillgång till. |
NEJ |
|
Längst ner i stacken finns en rad nivåer som skapas automatiskt av
systemet innan HTML- sidan läses in för bearbetning. Ovanpå dessa
kommer det att finnas flera nivåer beroende på vilka kommandon som
finns i sidan och var i körningen programmet är. När bearbetningen av
en sida är klar så skall det inte finnas fler nivåer i stacken än när
den startades.
All data som finns i stacken kan läsas men bara data och session under
Cart-taggen kan ändras/skapas med SET-kommandot från en webbsida.
Ett speciellt värde (som vi i fortsättningen kallar variabel) i
stacken refereras med och om man bara är
intresserad av det senaste namnet skriver man som då
söker uppifrån i stacken $.Namn gör samma sökning men nerifrån
istället.
Makrospråket är det verktyg designern har för att kunna hämta
information från systemet och att lägga in den i HTML-sidorna.
SBscript som vi kallar språket är mycket enkelt och stödjer bara det
absolut nödvändigaste. Det byggs ut med mer funktioner efterhand som
behoven blir mer krävande men grundstrukturen påverkas inte. När man
hämtar en sida från http-servern som slutar på .htm så startas en
speciell program-modul som går igenom sidan och bearbetar alla
kommandon i denna, resultatet dvs sida utan makro-taggar skickas till
användaren. Denna operation tar naturligtvis en viss tid så det är bra
om man bara kallar sidor som verkligen behöver processas för .htm, det
normala är som bekant att sidorna skall heta .html
Det finns två typer av operationer i språket, det ena är skriv ut och
det andra är hämta:
- Skriv ut
- Är den mest använda operationen och har inget
kommando som underlättar vid design. Att skriva ut ett
värde gör man genom att helt enkelt skriva namnet på vad man
vill skriva ut t. ex. <h1>Välkommen till
, butiken för dig!</h1>
kommer att bytas ut mot den text som
finns lagrad under ShopName i Shop-taggen på nivå 3 i
stacken. Om vi hade skrivet så hade detta
ersatts med tomrum då något sådant namn inte finns i
stacken.
- Hämta
- Operationen Hämta är flera olika kommandon som har det
gemensamt att de söker rätt på information ur databasen och
stoppar in denna i stacken eller skriver ut den istället för
kommandot. Kommandon skrivs alltid innanför
<% %>
taggar i HTML koden, om en variabel står innan för <% %>
taggarna skrivs den inte ut, utan den skall då höra till
något kommando.
<p>Kontakta oss
<%IF THEN%>
på fax
<%ELSE%>
med post
<%ENDIF%>.
</p>
Uppmanar besökaren att faxa om finns och har något
innehåll, annars får besökaren skriva brev.
Vissa kommandon t. ex. IF i exemplet ovan gör att ett stycke
HTML-kod visas ingen/en/flera gånger. Detta stycke kallar vi för
ett Block och det kan innehålla HTML-kod, utskrifter och
kommandon. på fax och med post ovan är två exempel på
block.
Teckenförklaring:
- query
- en databasfråga
- En variabel
- {...}
- Diverse programkod, allt ifrån ingenting till flera sidor.
- [ ]
- nårinting som kan utelämnas
- expr
- Ett matematiskt uttryck
- logical
- Ett logiskt uttryck
- string
- En textsträng
TEXT
NOCACHE
CALL string
CALL ID( expr_list )
PRINT expr
DEBUG
INCLUDE expr
INCLUDE_QUOTE expr
SELECT query [] [string]
FETCH query {...} DISPLAY {...} NEXTROW {...} ENDFETCH
DRAW ID( expr_list ) } [] [query] DISPLAY {...} [NEXTBLOCK {...}]
ENDDRAW
IF logical THEN {...} [ELSIF logical {...}] [ELSE {...}] ENDIF
SET [=] expr
= expr
POP var
PICTURE [( expr )]
PICTURE_DATA [( expr )]
FETCH query {...} DISPLAY {...} NEXTROW {...} ENDFETCH
- Namn:
FETCH
- Syntax:
FETCH Fråga {Block1} DISPLAY {Block2} NEXTROW {Block3} ENDFETCH
- Funktion:
- Hämtar information från databasen. Fråga anger vilken
fördefinierad fråga som skall anropas.
- Resultat:
{Block1} exekveras en gång före
frågan. Aktiva variabler: , ,
, , .
{Block2} exekveras en gång för varje post som
hittas. Aktiva variabler: , ,
, , , Alla variabler
från frågan. {Block3} exekveras en gång efter
frågan. Aktiva variabler: , ,
, ,
Sätt
till det antal rader man vill ha per sida, om
är odef. eller 0 visas alla rader. Skall en viss sida
visas så sätts
. Skall en sida innehållande en viss rad
visas så sätts
. Sätts båda ovanstående så gäller
. Första sidan/raden kallas nummer 1.
Om man vill att Block2 skall skall visas även om man inte fått någon
träff så sätt
till 1 eller sätt primärnyckeln
till tabellen till -1, så kommer ett (tomt) resultat upp.
Detta behövs för att kunna ta fram en post och visa den i samma
formulär oavsett om posten redan finns eller skall skapas.
En av de saker som gör systemet enkelt är att FETCH själv tar reda på
vad man vill visa för någonting genom att titta på stacken efter ett
antal variabler. Om FETCH hittar en primärnyckel så visas bara en
post. Om FETCH hittar någon annan nyckel så visas bara de poster som
har samma värde som denna. FETCH letar alltid från toppen på stacken
och neråt och stannar så fort den hittar någonting.
Resultatet av en fråga är oftast alla fält som databastabellen har
definierade, då en tabell angetts inom parentes betyder detta att den
returneras om den finns tillgänglig (LEFT JOIN). Efter att frågan
ställts lagras resultatet överst i stacken med frågans namn som tagg.
De frågor som man kan ställa med FETCH-kommandot definieras i en fil
på servern och de som rör kunddelen i de enklare butikerna är:
- Product
- Ger produkt utan variant-info, för butiker med varianter.
Primärnyckel: product_id
Övriga nycklar: shop_id, category_id
Resultat: Product
- Category
- Hämtar en/flera grupper
Primärnyckel: category_id
Övriga nycklar: shop_id, parent_category_id
Resultat: Category
- SubCategory
- Hämtar en/flera grupper, används för att hämta undergrupper
när man redan har
definierat.
Primärnyckel: INGEN
Övriga nycklar: shop_id, parent_category_id
Resultat: Category
- ProductVariant
- Ger produkt och en variant för butiker utan varianter.
Primärnyckel: product_id
Övriga nycklar: shop_id, category_id
Resultat: Product, Variant, (Unit)
- Variant
- Ger varianter, mest användbar om product_id är satt då man
får alla varianter till en vara.
Primärnyckel: variant_id
Övriga nycklar: shop_id, product_id
Resultat: Variant, (Unit)
- Variant_numrows
- Ger antalet varianter i
.
Primärnyckel: ingen!
Övriga nycklar: shop_id, product_id
Resultat:
- Item_numrows
- Ger antalet varor i
.
Primärnyckel: ingen!
Övriga nycklar: shop_id, category_id
Resultat:
- Group_numrows
- Ger antalet grupper i
.
Primärnyckel: ingen!
Övriga nycklar: shop_id
Resultat:
- vCampain
- Ger alla kampanjmärkta varor.
Primärnyckel: ingen!
Övriga nycklar: shop_id
Resultat: , 1, ,
, , ,
- Shipping
- Primärnyckel:
shipping_id
Övriga nycklar: shop_id
Resultat: Shipping
- Choose_Shipping
- Primärnyckel: ingen!
Övriga nycklar: shop_id
Resultat: Shipping
- Payment
- Primärnyckel:
payment_id
Övriga nycklar: shop_id
Resultat: Payment
- Choose_Payment
- Primärnyckel: ingen!
Övriga nycklar: shop_id
Resultat: Payment
- CART
- Ger innehållet i kundvagnen, det är olika varianter som ligger i
vagnen.
Inga nycklar
Resultat: Product, Variant, ,
- SEARCH
- Söker efter varor
Sökbegrepp i ord separerade med
mellanslag, komma, semikolon etc.
Sökmetod i AND eller
OR, blir AND om den ej specificerats.
Sökning i vilka fält i , default värden
(Product.Name, Product.Descr,
Product.Brand, Variant.TextID, Variant.Size)
Om man specificerar ISBN och sökbegreppet är ett giltigt ISBN
nummer så sker sökning endast i Variant.TextID fältet och då mot
samma ISBN-nummer.
Sökningen är av fritexttyp utom i artikelnummerfältet
Variant.TextID som måste ge en fullständig matchning för
att träffa. Vid sökning i textfält betraktas versaler och gemena
som samma tecken.
Sökresultat begränsas automatiskt till max. 200 träffar om
ingenting annat är satt.
- CATEGORY_TRACE
- Ger vägen av grupper från rooten till aktuell grupp
Indata
Retultat: Category
- CATEGORY_TREE
- Ger alla grupper under aktuell i snygg trädstruktur
Indata
Retultat: Category, (med aktuellt djup)
- PAGE_SELECTOR
- Stegar sig genom ett intervall av sidnummer (för närvarande hårdkodat
till 11). Skall utföras mellan FETCH och DISPLAY eller mellan
NEXTROW och ENDFETCH för att vara meningsfull. Dessa variabler
är aktiva under hela frågan:
, - första och sista
sidnummer på alla sidor
- Sidnummer på aktuell sida.
, - Sidnummer på första och sista sidan
som kommer att visas. Denna variabel är aktiv under loop delen:
- loopvariabel, går från till .
- PRICE_QUANTITY
- Ger alla stafflingspriser för en vara. Skall utföras innanför
FETCH Variant sats för att vara meningsfull.
Resultat:
= Antalsgräns för denna kolumn.
= Pris/st
= Pris per priskvantitet.
Det går inte att begränsa antalet returnerade rader på ovanstående
frågor förutom SEARCH.
IF ... THEN {...} ELSE {...} ENDIF
IF Expr THEN
Block1
ENDIF
IF Expr THEN
Block1
ELSE
Block2
ENDIF
Ett Expr är ett logiskt uttryck, i sin enklaste form bara en
variabel som är sann om den har ett värde skilt från 0 eller ''(tomma
strängen). Man kan jämföra variabler med varandra och med tal,
strängar och konstanter med följande operatorer:
- ==
- Likhet.
- !=
- Olikhet.
- > < >= <=
- Större än, mindre än, större eller lika med,
mindre eller lika med.
- %
- Modulus-operator (resten vid divison lika med 0 eller inte)
Det går tyvärr inte att skriva några mer avancerade uttryck, t.ex.
matematiska och parenteser och det saknas även AND,OR, NOT
funktionalitet, detta kommer att läggas till vad det lider.
En variabel skrivs som eller bara . Ett
tal skrivs som 5, strängar skrivs inom enkelfnuttar t.ex. 'Potatis'.
NOCACHE
Gör att sidan inte cachas hos användaren ( och i framtiden på servern )
<% SET 11 %>
<% = 11 %>
Det finns två olika sätt satt skriva en tilldelning på:
- Det gamala sättet:
SET värde
Obs inget = mellan variabel och värde.
- Det nya sättet:
= värde
Inget SET komando.
Alla variabler man tilldelar hamnar i
.
SELECT ID [] ['Options to include in HTML statement']
Skapar en select-kontroll och väljer aktuellt värde efter den
primärnyckel som hittas på stacken.
ID är antingen en vanlig fråga eller en speciell värdemängd. To_From
anger att svaret och defaultvärdet skall hamna resp hämtas från denna
variabel och inte från tabellens primärnyckel som man oftast gör.
Speciella ID:n för SELCT är:
- Tax_Class
- De momsklasser som definierats i butiken.
- Enter_Tax
- Med moms, Utan moms.
- show_level
- Utförligt, Ej bilder, Kompakt.
- parent_category_id
- Alla grupper som kan bli förälder till
denna. Dvs ej de som redan är barn till denna.
- GroupID
- Alla grupper som inte är gömda och hör till aktuell
butik. Om
är satt visas bara de som är
barn direkt under den gruppen.
- SPLIT()
- Delar upp selectvariabeln och
använder dessa delar som texter till selectlistan.
- SPLIT_EMPTY()
- Delar upp selectvariabeln och
använder dessa delar som texter till selectlistan. Lägger in ett
tomt alternativ först.
Variabler skrivs ut med någon av följande syntax: (allt skrivs in
inkl. klammer)
- Rå utskrift av variabelns värde, om det är
pengar så blir det exakt som det kommer från databasen.
- Samma som ovan men semikolonet anger var
variabelnamnet slutar. Används om man vill bygga ihop ett ord av
utskriften och något annat. t ex.
sida.html.
- Samma som första men
" tecken blir
" skall används då man skriver i attributfält i HTML
koden.
- Snabbformat för att formattera variablen som
pengar.
CALL CALLBACK_ID
Denna funktion används för att anropa någon speciell subrutin i systemet.
POP
Raderar , dvs tar bort namnet helt så att det inte
hittas vid sökning. Är mest användbart efter att man skapat/uppdaterat
en post och man sedan vill visa alla poster på resultatsidan.
Webbutik, onlinemanual