Lundsby
Bygger systemet bag den perfekte webshop

Køb et Amino Sponsorlink

Seneste indlæg

E-mail abonnement

  • E-mail: Abonner
  • E-mail abonnenter: 1

Arkiv

Befri din Webshop 2

(Advarsel: Man skal nok være lettere teknisk interesseret for at få noget ud af dette indlæg, eller for bare at gide læse det.)

Dette indlæg er en fortsættelse til "Befri din webshop", hvor jeg gennemgik argumenterne for valget af VTL som template sprog til EasyFlow platformen.

Når man bruger VTL som sprog, er det nødvendigt at lave et objekt hierarki der sætter brugeren/udvikleren i stand til at udtrække de data der ligger i systemet.

Node og nodetyper

EasyFlow er lidt anderledes end andre webshop systemer, i sin måde at håndterer data på. De fleste andre har faste definitioner af hvilket felter en side eller en varer indeholder. EasyFlow ligner i højere grad Umbraco eller SiteCore fordi det understøtter struktureret data. Hvor man selv bestemmer hvilket felter sider og produkt m.m. skal indeholde.

I EasyFlow kaldes de forskellige datadele for noder og hver node er skabt ud fra en nodetype, der bestemmer hvilket felter noden indeholder.

Reelt set giver node begrebet i EasyFlow, nogenlunde samme frihed som en relations database, begrebet er dog noget mere tilgængeligt for ikke programmører og passer bedre til modellering af sites.

Ovenstående skærmbillede viser redigeringsvinduet for nodetyper.

Udtræk af data og sprog baseret udvikling

For en del tid siden så jeg et foredrag med Martin Fowler og en anden fyr, der talte om sprog baseret udvikling, som en programmeringsstil. Ideen stammede fra en observation om at programmeringssprog i modsat til menneske sprog ikke huskede kontekst. Og at dette gjorde programmeringssprog unødvendigt kluntede at formulerer sig i. Dette illustreres bedst ved et eksempel: Hvis man f.eks. skal bestille en is, kunne man bruge flg. Sætning:

En is med en kugle jordbær, en kugle chokolade og en kugle vanilje.

I et programmeringssprog, vil dette typisk formulerer a la flg.

Var is = new Is();
is.TilføjKugle("jordbær");
is.TilføjKugle("chokolade");
is.TilføjKugle("vanilje");

Men hvis man i stedet lod metoden TilføjKugle returnere en reference til objektet selv (this), så kunne sætningen formuleres meget mere elegant:

Var is = (new Is()).TilføjKugle("jordbær").TilføjKugle("chokolade").TilføjKugle("vanilje");

Sprogbaseret udvikling egner sig rigtigt godt til VTL, fordi der er nemt at lave et objekt hierarki der understøtter udtræk af data.

Derudover har sprogbaserede udtræk, den fordel at det spiller ekstremt godt sammen med en editor der understøtter intellisense og errorhighlighting. Jeg har desværre ikke fundet en rigtigt god kode editor endnu, det eneste jeg kunne finde var nogle baseret på JavaScript som understøttede syntaxhighlighting.

Så det ender nok med at vi bliver nødt til at skrive vores egen i Flex. Det er målet at redigering af VTL skal være en ligeså lækker oplevelse som at redigerer C# i Visual Studio med Resharper. Jep, ambitionerne er tårnhøje, men vores Flex mand er også dygtig så mon ikke han klarer den.

Så er det på tide at kigge lidt på koden til feedet, den endte med at se som flg.:

01: <webgains>
02: #foreach( $node in $nodeRepository.GetByNodeType("Standardvare") )
03: #if ($node.IsSoldOut == false)
04:   <product>
05:       <product_id>$node.ProductCode</product_id>
06:       <product_name>$node.Name</product_name>
07:       <description>$node.GetProperty("Kort Beskrivelse").Value</description>
08:       <category>#if ($node.Parents.OfNodeType("Brand under Type").Count > 0)
$node.Ancestors.OfNodeType("Køn").Item(0).Name > $node.Ancestors.OfNodeType("Type").Item(0).Name#end</category>
09:       <price>$node.Price.Replace(",",".")</price>     
10:       <extra_price_field>$node.DiscountPrice.Replace(",",".")</extra_price_field>     
11:       <deeplink>#if ($node.Urls.Count > 0)$node.Urls.Item(0).Absolute#end</deeplink>
12: #set( $stortBillede = $node.GetProperty("Stort billede"))
13:       <image_URL>#if ($stortBillede.HasValue)$stortBillede.Url.Absolute#end</image_URL>
14:       <brand>#if ($node.Ancestors.OfNodeType("Brand").Count > 0)$node.Ancestors.OfNodeType("Brand").Item(0).Name#end</brand>
15:       <availability>in stock</availability>
16:       <delivery_time>1 day</delivery_time>
17:       <delivery_cost>0</delivery_cost>
18:    </product>
19:   #end
20: #end
21: </webgains>

Linie 02: NodeRepository bruges til hente en liste af alle noder af typen Standardvare og iterer over dem.
Linie 03: IsSoldOut bruges til at sikre at kunne varer der er på lager kommer med i feedet.
Linie 05: Varer nummeret skrives i feedet
Linie 06: Varens navn udskrives
Linie 07: Tekstfeltet kort beskrivelse hentes og skrives til feedet
Linie 08: Udfra hvilket noder varen ligger under skrives køn og type f.eks. Kvinder > Håndtaske
Linie 09: Prisen skrives og fordi det er et krav til feedet, så erstattes komma med punktum
Linie 10: Rabatprisen skrives
Linie 11: En url til selve varen skrives
Linie 13: En url til et billede af varen skrives
Linie 14: Mærket på varen skrives

Det var både hurtigt og nemt at skrive koden, ligesom jeg også tror at når næste feed skal implementeres, så vil det også foregå rigtigt hurtigt.

Selvom det er smart at kunne implementerer forskellige feed formater hurtigt. Så er den mest kræftfulde anvendelse af VTL uden tvivl at den sammen med Webservices kan bruges til at udvide hvordan et EasyFlow-baseret site opleves af besøgende. Man kan f.eks. udvikle flg. blog, forum, auktion, udlejning etc. Oven på EasyFlow løsning.
Overfor slutbrugeren vil udvidelser virker som en fuldstændigt integreret del af shoppen, ikke noget fedteri med iframes etc.

I de næste indlæg vil jeg prøve at gennemgå hvordan man udvikler ny funktionalitet ovenpå EasyFlow. Det må også snart være på tide med en status på vores outsourcing projekt og så er der også at Photoshop plugin som er ved at være klar.

Hvis du skulle være interesseret i at prøve beta'en af den nye platform, så kan skrive til mig på plu@easyflow.dk så sender jeg fluks et login retur.

Skrevet : jul 13 2009, 10:55 afLundsby| med7 kommentarer| | 3.615 Visninger

Kommentarer

Jespersagde:

Hej Lundsby.

Hvad med at trække logikken ud af formatet. Når du har lavet nogle flere feeds beslutter du f.eks. at du vil tilføje et defaultbillede der afhænger af produktets kategori (linje 12 og 13) og så skal du rette alle dine feeds med mere logik.

// Jesper

#den 16-07-2009 kl. 21:25
Er kommentaren brugbar? 0 0

Lundsbysagde:

Det er slet ikke nogen dårlig ide, det ville jeg evt. kunne implementer ved lave et sted hvor man kunne oprette variable erklæringer der blev kørt før feedsne.

Så kunne man centralt skrive noget a la

#set( $stortBillede = $node.GetProperty("Stort billede").WithDefault( $billede_fra_produktkategori )

Og lokalt i det enkelte feed ville der stå:

<image_URL>$stortBillede.Url.Absolute</image_URL>

og andet feed kunne f.eks. havde:

<productimage>$stortBillede.Url.Absolute</productimage>

Det tror jeg at jeg kører med.

#den 16-07-2009 kl. 23:15
Er kommentaren brugbar? 0 0

Niels Henriksensagde:

Jeg vil nok foretrække:

<productimage itemnumber="$ItemNumber" />

Men det er jo smag og behag ;)

#den 16-07-2009 kl. 23:31
Er kommentaren brugbar? 0 0

Lundsbysagde:

Jeg forstår ikke helt hvad $ItemNumber indeholder ? Kan du uddybe det ?

#den 17-07-2009 kl. 11:57
Er kommentaren brugbar? 0 0

Niels Henriksensagde:

jo klart...

for at vise et givent billede til en bestemt vare kunne man (det er sådan jeg gør det) lave:

<productimage itemnumber="[varnummer]" />

Men da varenummer ikke altid er det samme kan man lave en variabel på siden der sender varenummeret ud til html'en. Her har jeg så navngivet den $ItemNumber

#den 17-07-2009 kl. 12:00
Er kommentaren brugbar? 0 0

Jespersagde:

Hej Lundsby og Niels

Jeg synes det er noden der skal have styr på billedet og ikke feedet. Hvis f.eks. property 'Stort Billede' er tom for en knude er det fordi der ikke er sat et billede.

I feeded kunne vil jeg så typisk i stedet bruge 'Lille Billede', defaultbillede for kategorien eller defaultbillede for produkter uden billede.

Hvis man har en metode der levere det bedst mulige billede behøver man ikke tænke så meget når man laver hvert enkelt feed, altså noget i stil med:

billede = $node.findBedsteTilgændeligeBillede;

Jeg vil dog foretrække en URL og ikke som Niels foreslår et nummer, for så skal man efterfølgende lave opslag for at finde url'en. Men det er jo en smagssag.

// Jesper

#den 17-07-2009 kl. 13:54
Er kommentaren brugbar? 0 0

Lundsbysagde:

Hej Niels

Så forstår jeg det bedre, men i den struktur webgains krævede, skulle de bruge en hel url til billedet og varernummeret i product id tagget.

Med venlig hilsen

Peter Lundsby

#den 17-07-2009 kl. 22:31
Er kommentaren brugbar? 0 0
>