(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.
(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.)
For mig som udvikler er en af de mest irriterende mangler ved standard webshop så DanDomain, Scannet og os selv EasyFlow, at man ikke kan få lov at kode videre på dem.
Så selvom man har evner er det ikke muligt lige at kode den feature eller det layout, der skal til for at gøre ens shop eller site bliver helt perfekt.
Men det skal være slut, for et par dage siden fik jeg opgaven at lave et data feed til en af vores konsulent kunder, og i den forbindelse besluttede jeg at det er på tide at EasyFlow får et template sprog.
Det første valg jeg skulle træffe, var om jeg skulle bygge mit eget sprog eller finde et eksisterende som jeg kunne udvide. Jeg tænkte tilbage på kompiler konstruktion på universitet, og indså hurtigt at det ville være alt for omfattende at skrive sit eget sprog. Så jeg var altså tvunget til, at finde et eksisterende sprog som jeg kunne ændre så det passede ind i EasyFlow system.
EasyFlow er bygget på Microsofts .Net teknologi, så det var oplagt at kigge på hvordan andre systemer der er baseret på .Net havde implementeret deres template sprog. To af de Content Management systemer der har mest succes i .Net verden er SiteCore og Umbraco.
Begge bruger XSLT som template sprog, og en af grundene til det er at .Net platformen indeholder en XSLT motor, som gør meget af arbejdet for en. Det er også nemt, at udvide med egenudviklede .Net funktioner.
Dette gør XSLT til oplagt kandidat, men enhver der har prøvet arbejde med XSLT ved også at det ikke er en smertefrit. Til bestemte opgaver er XSLT unødigt kluntet og besværligt.
Dette er ikke fordi at skaberne af sproget ikke har tænkt sig om, snarer tværtimod. Sagen er den at XSLT er bygget til at kunne transformere meget store dokumenter (flere 100 mb). For at kunne gøre dette hurtigt, er det væsentligt at de forskellige linier/blokke af XSLT kan behandles parallelt. Så arbejdet kan fordeles ud over flere kerner og processorer.
Jeg arbejdede engang på et projekt i forbindelse med kommune sammenlægning, hvor vi skulle konvertere sags journaler. Havde XSLT ikke været så let at paralleliserer, så havde det været ubrugeligt for os.
Men når man bruger template sprog til at vise websider, så er evnen til parallel behandling typisk i ligegyldig. I stedet vil man havde et sprog der er så let og simpelt som muligt, man har ikke tid kluntet og besværlig syntaks.
Så jeg måtte ud at lede et andet sprog, der var lettere og mere intuitivt at bruge.
En af de væsentligst nyere platforme indenfor webudvikling, er Ruby-on-Rails. Det er et genialt framework, der ved at gøre simplere og hurtigere at skrive webapplikationer.
I lyset af Ruby-on-Rails' succes er der lavet adskillige Rails inspirede frameworks, til de forskellige platforme. Java har Groovy on Grails, Python har Django osv. og på .Net platformen har vi Castle og ASP.Net MVC.
Specielt Castle projektet er interessant i forbindelse med template sprog, for det bruger et sprog der hedder VTL. Sproget er skrevet til at være let og simpelt at bruge og lærer. Hvilket betyder at sproget et meget lille ordforråd og kan læres på omkring en 30 minutter, hvis man er vant til at programmerer.
Sproget er faktisk så simpelt, at jeg ville tro at det også er nemt at lærer selvom man ikke kan programmerer. Det eneste man skal gøre er at læse guiden til sproget, også skulle man være kørende.
Måden man udvider sproget, så det kan snakke med EasyFlow løsningen er ganske simple. For VTL gør det muligt at eksponerer almindelige .Net objekter, som efterfølgende kan manipulerer via VTL.
Indtil videre er jeg meget tilfreds med VTL, det har vidst sig både hurtigt at arbejde med og at udvide.
I næste indlæg vil jeg vise koden til data feedet og samt hvad man mere kan bruge VTL i EasyFlow.