Nieuwe FM Brussel website

fmbrusselStadsradio FM Brussel lanceerde een paar weken geleden een nieuwe website. Marlon zorgde voor de uitwerking van het design en de volledige ontwikkeling van de website.

De vorige versie van de website, gelanceerd in 2004, werd ook door ons gebouwd. 6 jaar later was het dringend tijd voor een volledige vernieuwing. Het op maat gemaakte Content Management Systeem (CMS) dat de redactie gebruikt om de website up to date te houden werd grotendeels behouden; het systeem werd alleen op een aantal punten uitgebreid of aangepast.

Het is vooral de website zelf die grondig werd aangepakt. Van design tot wat er precies waar getoond wordt, alles werd vernieuwd. De homepagina wordt veel vaker geupdate, achterliggende pagina’s kregen related content, er wordt gebruik gemaakt van tags en de redactie kan razendsnel artikels verzamelen in nieuwe overzichtspagina’s (bij een bepaalde gebeurtenis, evenement of rond een bepaald thema).

Ook het aanbieden van audio werd volledig herbekeken. De live player is niet enkel meer het ding waarmee je naar de radio luistert, maar biedt een twitter feed aan en de meest recente artikels van de homepagina. De on-demand player biedt de audio nu ook aan als een stream, zodat je razendsnel kan doorspoelen naar een onderdeel in het programma, zonder eerst het hele bestand te moeten inladen. De on-demand player is ook uitgebreid met gerelateerde inhoud en extra audio fragmenten. Beide players werken op basis van een Flash Media Server stream.

Doorheen de site wordt ook inhoud van elders ingepast zoals Flickr slideshows, YouTube video’s, twitter feeds, RSS feeds, etc..

Monsterlijke case study

Eind januari lanceerden we de nieuwe webshop voor de babyspeciaalzaak Monsters With An Attitude. Deze webshop is, net zoals alle andere webshops & projecten die we afleveren, “tailor made” naar de noden en wensen van de klant.

Zowel de look&feel als de functionaliteit werden vastgelegd na enkele rondes feedback en aanpassingen samen met de klant. Een goed inlevingsvermogen in de business en werkwijze van de klant laat toe om het aantal iteraties tot een minimum te houden terwijl we naar een maximum aan klantentevredenheid streven.

Wie de vorige posts op deze blog gelezen heeft weet dat we bepaalde ontwikkelings- en functionaliteitsprincipes hanteren. We kunnen ze gerust “web industry best practices” noemen. Wat nu volgt is een mix van een case study en whitepaper voor een webshop.

Analyse: analyse this

PrototypingEerst en vooral hebben we de analysefase. De eerste sessies met de klant zijn eerder brainstormsessies. Alle mogelijke functionaliteiten, inclusief de toeters en bellen, die relevant kunnen zijn voor dit type project worden uitvoerig besproken. Op het einde van de analysefase leggen we samen met de klant vast wat er zal worden uitgewerkt, hoeveel dat zal kosten en hoe lang dat zal duren. Vaak wordt er op dit ogenblik beslist om bepaalde opties al dan niet meteen te nemen of te verschuiven naar een volgende fase. Dankzij deze gefaseerde aanpak kan een project geleidelijk groeien.

Heel belangrijk is dat, naast de functionaliteit, ook de business processes van de klant mee onder de loupe worden genomen.  In overleg worden scenario’s opgesteld voor de verschillende types van gebruikers (doelpubliek) die de website gaan gebruiken. Een gebruikerscenario identificeert handelingen met stappen en acties die moeten gebeuren om bepaalde doelen te kunnen bereiken.
Tijdens de analysefase staan deze gebruikerscenario’s centraal. Enerzijds bepalen ze de functionaliteit en logica. Anderzijds kunnen ze worden gebruikt ter controle of alle afgesproken functionaliteiten zijn verwerkt, maar ook of de website gebruiksvriendelijk en logisch is opgebouwd.
Uit de hele analyse vloeit uiteindelijke een prototype. Vincent had enkele posts terug over dit punt al een interessante uiteenzetting online geplaatst.

Design: het uithangbord

Tijdens de analysefase kan ook al aandacht worden besteed aan de look&feel van de webshop. Onderschat het belang hiervan niet. Een shop moet niet alleen functioneel goed werken, het moet er ook professioneel uitzien en vertrouwen wekken. Bovendien wordt de webshop het uithangbord voor de winkel. Een reden te meer om een knap en origineel design af te leveren. De klant weet op dit vlak meestal wel heel duidelijk waar hij naartoe wil. Onze designer Gert wist, zoals altijd, enkele verbluffende, toepasselijke designs uit zijn mouw te schudden.

mwaa-design-2mwaa-design-3
mwaa-design-4

Ontwikkeling: goede afspraken

Na deze eerste fases, die meestal wel parallel verlopen, start de technische ontwikkeling van de webshop. Tijdens de interne, technische kick-off meeting worden heel wat zaken besproken. We spreken goed af hoe de zaken technisch geïmplementeerd zullen worden. Doorgaans volgen nu 3 grote brokken in de ontwikkeling:

  • Back-end development: dit houdt in dat de functionaliteit en bedrijfsprocessen die eigen zijn aan de webshop in code worden vertaald. Daarbij moet er ook communicatie naar een databank of externe systemen zijn.
  • Front-end development: de design templates worden opgeknipt en vertaald naar XHTML, CSS en Javascript. Onderschat het belang van deze taak niet want hier leggen we de basis voor de Search Engine Optimalization (SEO).
  • De laatste brok is de integratie van de back-end-ontwikkeling met de front-end-ontwikkeling.

Fasering, iteratie en klantfeedback

De ontwikkeling wordt opgedeeld in fases op basis van functionaliteit. Iedere fase wordt ontwikkeld en getest voor men naar de volgende fase overstapt. Veelal steunt een latere fase op eerder ontwikkelde fases dus is het van extreem belang dat men iedere fase goed test. Unit testing is hierbij een grote hulp.

Een belangrijk voordeel van fasering is dat men op het einde van iedere fase feedback kan vragen van de klant. Zo vermijdt je eventuele “verrassingen” op het einde van de complete ontwikkelingscyclus. Betrek je klant zo snel mogelijk bij de ontwikkeling. Iedere fase waarbij men binnen een korte periode een bepaalde functionaliteit ontwikkelt, test en ter goedkeuring voorlegt aan de klant noemt men een sprint.

Best practices

Er zijn een aantal best-practices die we in de kijker willen zetten:

  • CSS sprites: we voegen een aantal afbeeldingen samen tot één afbeelding. (voorbeeld)
  • Custom fonts door gebruik te maken van Adobe Flash.
  • Search Engine Optimized (SEO) url’s & content.
  • Gebruik van Ajaxvoor het winkelmandje met als doel een betere user experience.
  • Meertaligheid. Je kunt argumenteren dat dit een functionaliteit is en geen “best practice”. Je kunt je echter geen Europese webshop inbeelden zonder. Meertaligheid is een “must”. Momenteel is de webshop van Monsters With An Attitude beschikbaar in één taal. De shop is zo ontwikkeld dat het toevoegen van extra talen slechts een administratieve kwestie is. Het leuke aan de meertaligheidsfunctie is dat wanneer men van taal verandert men op dezelfde pagina in de andere taal terecht komt. De meeste sites gaan bij het switchen van taal naar de hoofdpagina waardoor men de gebruiker verplicht om opnieuw een product of pagina te zoeken. Bij good practices hoeft dit niet. “It’s what separates the men from the boys”

Beheermodule: geen dubbel werk

Als laatste willen we je ook even laten meekijken achter de schermen want de publieke webshop is slecht de helft van de webapplicatie.

Deze beheersmodule laat toe de gegevens van klanten, producten, bestellingen en stock te beheren. Daarnaast is er ook nog volledige synchronisatie voorzien tussen de database voor de webapplicatie en de Filemaker-software in de winkel zodat de klant geen dubbel beheer moet doen voor de fysische winkel en de webshop.

De beheersmodule laat o.a. de volgende zaken toe:

  • Beheer klanten, producten, bestellingen en stockindicatie;
  • Printen BTW-listings, verkooplijsten;
  • Printen van facturen, inhoudsdocumenten, plakbonnen & transportdocumenten;
  • Printbare facturen en creditnota’s zijn PDF-documenten die dynamisch worden gegenereerd.
  • Verzenden van betalingsherinneringen.

Beheersmodule

Oh ja, de ontwikkeling gebeurde in ASP.NET. Maar dit is slechts een triviaal gegeven.

Verdere informatie over dit project kan je terugvinden op de projectpagina

3 systemen die je webapplicatie een pak flexibeler maken

De website van de Vlaamse Diabetes Vereniging, bijna een jaar geleden gelanceerd, is een website én extranet met een zeer uitgebreide functionaliteit. De website zelf bestaat uit content (nogal wiedes), een shop, en websites voor de lokale afdelingen. Daarnaast is alles beheerbaar door de vereniging zelf, en kunnen de vereniging en bepaalde bestuursleden van plaatselijke afdelingen aan ledenbeheer doen.

Een beslissing die we zeer vroeg bij de ontwikkeling hebben genomen, is om vooraf op 3 manieren flexibiliteit in te bouwen: 3 plug-in-systemen, die binnen de kern van de applicatie draaien, en die er voor zorgen dat we snel extra systemen, tools of aanpassingen kunnen inpassen, zonder aan de kern te raken:

  • jobs: een job is een stuk functionaliteit dat op een vast tijdstip of om de zoveel tijd wordt uitgevoerd;
  • rendering helpers: plug-ins die de HTML van alle pagina’s of een bepaald type pagina herwerken, vlak voordat die naar de browser wordt gestuurd;
  • listeners: plug-ins die luisteren naar en reageren op welbepaalde acties binnen de website en het extranet, zoals het aanmaken van een pagina, het plaatsen van een bestelling, een lid dat zich aanmeldt.

Jobs

Binnen de webapplicatie hebben we een ‘job’-systeem gebouwd: een systeem dat ons toelaat extra functionaliteit toe te voegen, die op een welbepaald tijdstip (bijvoorbeeld elke dag om 8u30) of om de zoveel tijd (bijvoorbeeld om de 3 minuten) wordt uitgevoerd.

De kerntaak van het systeem is: de plug-ins die jobs bevatten inladen en deze uitvoeren, volgens de bepaalde instellingen (aantal keren per dag of om de zoveel minuten, in een apart proces of niet).

Eenmaal dat de motor van dit systeem er was, konden we achteraf eenvoudigweg jobs toevoegen. Op dit ogenblik zijn er 6 jobs actief op de website:

E-mail queu job

Her en der in de website en het extranet zijn er pagina’s of formulieren die e-mails uitsturen: het formulier om lid te worden, de tell-a-friend, de webshop, enz.

Om de applicatie onafhankelijk te maken van het proces dat de e-mails effectief uitstuurt (de SMTP-server) maken we gebruik van een e-mail queu. Als bijvoorbeeld een lid een bestelling plaatst, wordt de e-mail niet onmiddelijk uitgestuurd door het systeem dat de bestelling afhandelt, maar wordt dat bericht in een wachtrij geplaatst.

Laten we de e-mail namelijk rechtstreeks vertrekken en is op dat moment de SMTP-server onbeschikbaar, zou in het geval van de webshop de bestelling niet kunnen worden geplaatst.

De e-mail queu job gaat met een vast bepaald interval in de wachtrij kijken of er e-mails moeten worden verstuurd  en zorgt voor de volledige afhandeling: SMTP-server contacteren, e-mail uitsturen, eventueel optreden als de SMTP-server niet beschikbaar is (we bepalen het aantal mogelijke retries per e-mail), de applicatie verwittigen als de e-mail effectief is uitgestuurd, eventueel extra functionaliteit uitvoeren wanneer de e-mail wel of niet verstuurd is, enz.

E-mail Nieuwsbrief-job

Deze job kijkt of er campagnes voor de e-mailnieuwsbrief beschikbaar zijn. Indien een campagne mag worden verstuurd, zorgt deze job voor het aanvullen van de e-mail queu, die op zich dan weer het uitsturen verzorgt, met de nodige afhandelingen: namelijk het systeem van de e-mailnieuwsbrieven feedback geven over elke verstuurd e-mail: verstuurd, niet verstuurd, fout in het adres van de ontvanger, …

Blog feed job

Voor de jongeren binnen de vereniging werd een blog opgezet, in WordPress. De titels van de blogartikels worden op de homepagina van de eigenlijke website getoond. Hier bestaat weer het gevaar dat de blog niet beschikbaar is en dus de nodige links naar artikels niet op de website kunnen geladen worden. Vandaar het loskoppelen en het gebruik van een job die om de zoveel minuten de RSS feed van de blog inleest en de nodige aanpassingen doet op de website.

Search engine indexer en spell check indexer job

De search engine van de website werkt op basis van Lucene.NET, een .NET port van de Java text search engine.

De website op zich bestaat uit heel wat dynamische pagina’s (deze worden regelmatig aangepast), maar ook statische bestanden (.ascx files, of anders gesteld: .NET controls) waarin teksten staan die nooit of amper moeten aangepast worden. Bij het aanmaken, aanpassen of verwijderen van alle dynamische pagina’s, wordt de search engine verwittigd dat de index moet worden aangepast (zie het Listeners systeem). Wijzigingen in de statische bestanden kan de search engine niet detecteren.

Daarom hebben we een eigen crawler gebouwd die vertrekt vanop de homepagina en zo van link tot link, door de website loopt en de nodige pagina’s indexeert en toevoegt of aanpast in de index van de search engine.

Daarnaast draait er een tweede job die nodig is om de search engine nog beter te maken: een spell checker job. Dit laat ons toe suggesties te geven bij fout getypte zoektermen. De index van de search engine, wat eigenlijk een lijst is van alle woorden die op de website staan, wordt daarom door deze job om de zoveel uur overlopen en alle unieke woorden in de index worden opgelijst en bewaard. Zo komen we tot de ‘Bedoelde je xxx’-suggesties.

Externe applicatie check job

De website en het extranet communiceren continu met een extern systeem dat door de VZW wordt gebruikt om haar ledenbestand te beheren. Om problemen met de communicatie met dit systeem snel te onderkennen, controlleren we door middel van een job de beschikbaarheid van die externe applicatie.

Rendering helpers

De VZW heeft meer dan 20 plaatselijke afdelingen die elk beschikken over een klein onderdeel binnen de website dat ze zelf kunnen beheren. Het centrale secretariaat is niet in staat om voortdurend te controlleren of de pagina’s correct zijn opgemaakt, en of ingebrachte inhoud consistent is met de layout van de rest van de website. Daarom hebben we de Rendering helpers gebouwd.

De Rendering Helpers is een systeem dat, ook weer door middel van plug-ins, de output die naar de browser wordt gestuurd, aanpast indien nodig. Dus ook dit is een systeem dat vandaag een aantal modules bevat en dat makkelijk kan worden uitgebreid.

De Rendering Helpers die vandaag actief zijn op de site zorgen er bijvoorbeeld voor dat:

Te grote beelden

Beelden die worden ingevoegd door iemand van een plaatselijke afdeling, en die te groot zijn om binnen de layout te passen, worden aangepast en on the fly verschaald. De mensen die die pagina’s beheren hebben meestal niet de nodige tools om foto’s zelf te bewerken. Daarom stoppen ze vaak digitale foto’s met hun originele breedte en hoogte in een pagina. Het effect is dat het beeld, kleiner gemaakt om in de layout te passen, niet mooi is, en het beeld veel te zwaar is (in kilobytes) om in een website goed te werken. De Rendering Helpers zorgen dat het beeld dynamisch kleiner wordt gemaakt, zodat de kwaliteit hoger ligt en de persoon die de pagina bezoekt geen te groot bestand moet inladen.

Tabellen voor layout omzetten naar <div/> elementen

De website bevat geen tabellen om de layout mee te bepalen (met layout bedoelen we hier welke elementen waar op de pagina staan). Maar voor de mensen die de inhoud ingeven, is het gebruik van tabellen makkelijk om verder te gaan dan de standaard vloeiende bladspiegel: tekst die van boven naar onder loopt. Daarom hebben we Table Layout Helper gebouwd. Deze zet, bij het opbouwen van de pagina, en net voor deze naar de browser wordt gestuurd, de layout die in een tabel zit om naar HTML-code die wel de webstandaarden respecteert.

HTML-optimalisatie

Naast bovenstaande interventies worden o.a. lege paragrafen verwijderd, <font/> tags vervangen, enz.

Dergelijke optimalisatie is echter nooit afgerond. Steeds ondervinden we opnieuw dat pagina’s gevuld zijn met incorrecte HTML-elementen of -structuren. We bouwen dus steeds extra Rendering Helpers die dergelijke fouten gracieus oplossen.

Listeners

Listeners zijn een concept dat bij de meeste programeertalen al lang bestaat. Voor deze applicatie hebben we binnen de basisfunctionaliteit een gelijkaardig principe ingevoerd: nieuwe systemen (plug-ins) die worden toegevoegd, luisteren naar bepaalde acties binnen de applicatie. Wordt die actie uitgevoerd, dan worden alle luisteraars verwittigd en krijgen ze de nodige gegevens.

Zo vuren we verschillende plug-ins aan als een lid zich aanmeldt, als een pagina wordt aangemaakt of aangepast of verwijderd, als een bestelling wordt geplaatst, enz.

Een dergelijk systeem zorgt er opnieuw voor dat er  aan de basiswerking niets moet worden gewijzigd. De applicatie houdt zich bezig met de essentie. Andere systemen schakelen zich in en luisteren dus naar wat binnen de applicatie gebeurt.

Content Indexing Listeners

Een van de listeners die actief is binnen de applicatie ‘luistert’ naar nieuw bewaarde inhoud, inhoud die gewijzigd wordt en inhoud die verwijderd wordt. Zo wordt de Index die de search engine gebruikt steeds up to date gehouden.

Conclusie

Kortom, 3 eenvoudige systemen met één gezamelijk doel: flexibiliteit. De website en webapplicatie, zoals die vandaag is gebouwd, is klaar voor uitbreidingen van morgen.