Onze eerste website bouwen met Drupal 8

Vanwege het 10-jarig bestaan van ons bedrijf zijn we druk bezig geweest met het herdefiniëren van onze strategie en missie. Onze manier van werken met onze klanten is in de loop der jaren geëvolueerd en onze huidige website weerspiegelde niet langer de manier waarop we momenteel projecten uitvoeren. Waar onze vorige website enkel een grote lijst van onze klanten en projecten toonde, willen we niet langer enkel focussen op het eindproduct, maar eerder op het proces om tot dit eindproduct te komen. Het was tijd voor een revisie van de website van ons bedrijf.

Wat door de jaren heen constant is gebleven, is onze liefde voor Drupal. We gebruiken het al jaren en door de meeste van onze projecten op dit framework te ontwikkelen, konden we vertrouwen op interne (en externe) standaarden, waardoor we de basis van elk project snel konden ontwikkelen en ons konden richten op het ontwerp en de interactie en andere meer projectspecifieke functies.

Drupal 7 is al jaren ons go-to framework en heeft ons en onze klanten door de jaren heen goed gediend. Hoewel een basisinstallatie van Drupal 7 voldoende was voor kleinere projecten, hadden de meeste van onze projecten vrij veel modules van derden (bijdragen) nodig, zelfs zoveel dat veel modules als een noodzakelijk onderdeel van Drupal core konden worden beschouwd. Voorbeelden hiervan zijn i18n (internationalisatie), views, pathauto (automatische URL aliassen), entity API, file entity en media. De kwaliteit van deze modules was op het niveau van de Drupal-standaarden en het installeren en gebruiken ervan was meestal een eenvoudig proces.

Drupal 8 was al geruime tijd geleden aangekondigd, er werden zelfs al plannen voor gemaakt bij de lancering van Drupal 7, wat zo'n beetje standaard is voor Drupal. De plannen waren groots, mogelijk de grootste herschrijving in de geschiedenis van Drupal. Tijdens de levensduur van Drupal 7 zijn er veel functies toegevoegd met contrib modules die de core release niet hebben gehaald. Het beste voorbeeld is waarschijnlijk de Entity API-module, een uitbreiding op de entity API van de core met als doel het standaardiseren van een uniforme manier om om te gaan met entiteiten en hun eigenschappen. Veel contrib modules maken gebruik van deze entity API, waardoor het de facto een vereiste is voor de meeste projecten. Drupal 8 zou deze uniforme manier van omgaan met entiteiten in core opnemen. Een ander groot gat in Drupal 7 core was i18n, dat nu volledig is opgenomen in Drupal 8 core. Maar bovenal is de grootste verandering in Drupal 8 zonder twijfel de integratie van het Symfony-framework, waardoor het framework effectief verschuift van een procedureel naar een objectgeoriënteerd framework, waardoor het framework toegankelijk wordt voor een veel groter publiek, met name voor ontwikkelaars die gewend zijn aan het Symfony-framework.

Een paar jaar geleden besloten we om interne ontwikkeling te standaardiseren, het was tijd om Drupal 8 uit te proberen en te kijken of het bruikbaar was voor productieklare websites. Wat is een betere manier om een platform te testen dan het te gebruiken voor een echt project, met echte vereisten?

Pre-release versies

We zijn begonnen met het testen van Drupal 8 in de vroege stadia, nog voor de eerste bètaversie. Uit ervaring weten we dat het over het algemeen een slecht idee is om met een echt project te beginnen op niet-bètaversies, omdat de ontwikkelaars meestal nog niet zijn begonnen aan een upgradepad, wat betekent dat structurele veranderingen in de kern kunnen leiden tot verlies van gegevens en structuur tijdens de upgrade, of erger nog, een niet-functioneel platform. Desondanks waren we vastbesloten om het op een echt project uit te proberen, omdat we anders zeker wisten dat we bugs, ontbrekende functies en andere zwakke punten zouden missen.

We begonnen zoals we altijd doen: het opzetten van een basissitestructuur. We zetten een paar inhoudstypen op, veranderden hun weergavemodi, voegden een paar weergaven toe, zetten een navigatiestructuur op en voegden wat dummy-inhoud toe (we hadden nog lang geen echte inhoud). Toen begonnen we met het opzetten van een thema zoals we normaal zouden doen: een basisthema ontwikkelen, gebaseerd op een aangepaste versie van Twitter Bootstrap, en het basisthema uitbreiden met een subthema voor het ontwikkelen van de daadwerkelijke lay-out van de site.

Het verliep soepel, we herkenden veel best-practices van Drupal 7 en waren erg blij dat ze in core waren opgenomen. Vertalingen waren eenvoudig in te stellen, en we waren erg blij dat contentvertaling niet langer een optie is, en entiteit- (of veld-) vertaling de standaard was. Weergaven maken

Core-functionaliteit

Meteen nadat we de mogelijkheden van D8 begonnen te verkennen, zagen we dat veel best-practices uit D7 in de core waren opgenomen en we waren erg blij dat we deze richtlijnen al volgden, omdat dit betekende dat de overstap naar D8 eigenlijk niet al te groot voor ons was.

Symfony integratie

De grootste stap voor D8 was waarschijnlijk de integratie van het Symfony-framework. Ook al betekende dit in feite een complete herschrijving van een groot deel van Drupal, het was een zeer verstandige stap. Niet alleen stelt het zowel D8 als Symfony open voor een hele nieuwe groep ontwikkelaars, maar het betekent ook dat de Drupal-gemeenschap zich meer kan richten op het verbeteren van het CMS-gedeelte en zich niet bezig hoeft te houden met het onderhouden van de onderliggende basisstructuur. Dit betekent ook een verschuiving van een procedureel systeem naar een meer objectgeoriënteerd systeem. Op het eerste gezicht is de code echt goed gestructureerd, maar we schrokken er wel een beetje van: betekent dit dat we helemaal opnieuw moeten leren wat we de afgelopen jaren hebben geleerd?

Plugins, services en hooks

Plugins en Services zijn in feite het OO-equivalent van het oude op Hooks gebaseerde systeem, en het lijkt erop dat, hoewel er nog steeds veel Hooks aanwezig zijn, ze langzaam worden uitgefaseerd en moeten worden vervangen door Plugins of Services.

Voorbeelden van Plugins zijn bijvoorbeeld modules die aangepaste typen blokken bieden met andere eigenschappen dan gewone blokken, of plugins die nieuwe typen velden bieden, zoals een kleur- of adresveld. Deze Plugins worden geleverd door de standaard klassen te erven, zoals BlockBase of FieldItemBase, en de benodigde methoden te implementeren.

Voorbeelden van Services zijn bijvoorbeeld een Cache service die leest van en schrijft naar een caching backend, zoals Memcached, Redis, MongoDB of zelfs het bestandssysteem. Services zijn onderling uitwisselbaar en worden geleverd door verschillende interfaces te implementeren, in dit geval als de CacheBackendInterface.

Theming met Twig

Drupal 7 gebruikt standaard PHPTemplate als templating-engine. De setup was erg flexibel en stond ook andere backends toe, maar in de praktijk werd meestal PHPTemplate gebruikt. Voor ontwikkelaars was het een erg makkelijk systeem om te gebruiken, omdat het dezelfde taal gebruikte als de core en modules. Het directe nadeel was dat het ontwikkelaars toestond om inline PHP-code te gebruiken, en dus business login in de templating engine. We hebben beginnende ontwikkelaars SQL-queries zien doen vanuit de templates.

Voor Drupal 8 is gekozen voor de Twig templating engine, voornamelijk omdat dit de engine bij uitstek is voor Symfony. Twig zelf is erg eenvoudig en vergt weinig tijd om eraan te wennen. Het grootste verschil tussen Drupal 7 en 8 is dat in Drupal 8 alles een Twig-template is geworden. In Drupal 7 had je nog de keuze om ofwel een template bestand te gebruiken, ofwel een thema functie, die rechtstreeks een HTML string uitvoert. Dit maakte het soms moeilijk om te bepalen waar de output vandaan kwam. In Drupal 8 wordt in principe alles uitgevoerd via een Twig-template, zelfs kleine dingen zoals invoervelden of links. Dit maakt het veel gemakkelijker om sjablonen te ontwikkelen en zorgt voor een extra cacheerbare laag, omdat Twig compileert naar PHP-code.

Contrib modules status

Bij de meeste van onze websites en platformen was de kernfunctionaliteit gewoon niet genoeg, dus bevat ons installatieprofiel standaard heel wat contribmodules. Sommige daarvan zijn geïntegreerd in core, terwijl andere afhankelijk zijn van de bijdragen van anderen.

LESS

We zijn een grote fan van CSS preprocessors, zoals SASS en LESS. We hebben gewerkt met een aangepast thema, gebaseerd op een aangepaste versie van Twitter Bootstrap. De broncode van Twitter Bootstrap is gebaseerd op LESS, dus het was eenvoudig te integreren en aan te passen. Drupal 8 heeft echter geen volledig functionerende LESS-module, en hoewel er werd gespeculeerd dat een soort CSS-preprocessor in Drupal 8 core zou komen, is deze nooit uitgebracht, dus moesten we op zoek naar andere opties. Gelukkig heeft Grunt erg goede LESS ondersteuning met grunt-contrib-less, dus we hebben een kleine taak gemaakt door grunt-contrib-watch te gebruiken. Elke keer als we ons LESS bestand opslaan, haalt de watch-task het op en compileert ons CSS bestand opnieuw voor ons. Hoewel dit geen optimale Drupal-integratie biedt (het genereert één CSS-bestand voor elke pagina, dus geen optie om aparte LESS-bestanden per pagina te genereren), veranderde het onze basisworkflow niet.

Weergave Suite

Display Suite (DS) is een van die modules die altijd al deel uitmaakte van onze toolset. Het biedt een mooie manier om de output van de HTML te bepalen, vanuit het CMS, zonder dat je hoeft uit te zoeken waar de HTML vandaan komt in Drupal (was het een template bestand, of een render array, of een thema functie?).

DS bevond zich in een bètafase toen we begonnen met ontwikkelen, maar was al redelijk bruikbaar, op een paar kleine dingen na. Een groot probleem met DS is echter dat je alles vanuit Drupal moet configureren, er was geen juiste manier om dingen met code te doen, wat betekende dat het moeilijk was om versiebeheer uit te voeren over je aanpassingen, zonder je toevlucht te moeten nemen tot Drupal-functies. Nu Drupal 8 alles vanuit een Twig template bestand heeft, is het vrij eenvoudig om de output van elk element vanuit code te bepalen, wat zorgt voor perfect versiebeheer. Dit zou kunnen betekenen dat we niet langer de noodzaak voelen om Display Suite te gebruiken.

Veldgroep

Wanneer we onze output wilden structureren, gebruikten we Fieldgroup om ons te voorzien van wrapper-elementen om de velden van een entiteit te scheiden. Het heeft echter dezelfde problemen met versiebeheer als DS, en hoewel de integratie met Features erg goed is, hebben we deze workflow nooit echt prettig gevonden. Nogmaals, met Twig hadden we het gevoel dat het niet langer echt nodig was, omdat we alles konden doen wat we wilden met behulp van Twig-sjablonen.

Paragrafen en panelen

Zowel Paragraphs als Panels vormden een groot deel van onze workflow, afhankelijk van de grootte en complexiteit van het project. Beide modules werden bijna vanaf het begin ondersteund en waren verrassend stabiel. Voor het bouwen van onze huidige site hebben we alleen Paragraphs gebruikt, maar het uitproberen van Panels gaf ook zeer goede resultaten.

Configuratiesysteem

Een van de grotere nadelen van vorige Drupal versies was de mix van data (inhoud) en configuratie (instellingen) binnen de database. Een simpele wijziging in je ontwikkelomgeving (bijvoorbeeld de output van een veld) werd naar de database geschreven (als geserialiseerde PHP struct, niet minder). Bij voorkeur zouden dergelijke wijzigingen in code staan, zodat deze versiebeheerbaar is en eenvoudig van omgeving naar omgeving verplaatst kan worden. De oplossing hiervoor was het gebruik van de Drupal Features-module. Features integreerde in principe met Drupal door wijzigingen in configuratie-instellingen (en gegevens, als je dat zou willen) bij te houden en deze weg te schrijven naar PHP-code, pakketten in een module. Dit werkt prima, maar betekende wel dat er veel extra modules nodig waren, en het betekende ook dat modules een manier moesten hebben om Features hun wijzigingen te laten weten. Dit betekent dat je veel hooks moet integreren die de module Features biedt, en dat betekent veel werk voor de ontwikkelaars.

Drupal 8 wordt geleverd met een geïntegreerd configuratiesysteem, verrassend genoeg het Configuratiesysteem genoemd. Omdat het in core zit en bedoeld is om te worden gebruikt als de standaard manier om de instellingen van een module te configureren, was ondersteuning nu site-breed. Configuration System is zeer configureerbaar, schrijft standaard naar een database en integreert met veel backends, zoals bestandsgebaseerde opslag (voor versiebeheer), MongoDB, Redis, enz. Het wordt zelfs geleverd met standaard tools zoals Configuratie Synchronizer.

Gridster module

Last, but not least, was onze nieuwe uitdaging: het schrijven van onze eigen aangepaste module voor Drupal 8. Onze ontwerpers hebben gewerkt aan een nieuwe identiteit voor ons bedrijf, die veel onregelmatige rasters van foto's bevat. Om onze tekstschrijvers in staat te stellen deze rasters op onze website te gebruiken, zonder dat ze afhankelijk zijn van aangepaste gecodeerde HTML-blokken, wilden we een module ontwikkelen waarmee ze deze rasters net zo gemakkelijk kunnen beheren als hun tekst. We vonden een erg coole JavaScript-plugin genaamd Gridster en wilden deze graag integreren in onze Drupal-website.

Dit betekende veel prototypes maken, tutorials en documentatie lezen en wennen aan de nieuwe manier van modules ontwikkelen.

Conclusie

Alle standaarden die we in Drupal 7 toepasten, zijn nu Drupal 8-standaarden geworden. De meeste contrib modules zijn nog wat instabiel en nog in ontwikkeling. Dus voordat we de websites van onze klanten migreren, moeten we er eerst zeker van zijn dat de gebruikte modules stabiel zijn, zodat we de stabiliteit kunnen garanderen.

De code is substantieel veranderd, dus er is veel dat we moeten leren, maar de structuur is een stuk beter. Het migreren van Drupal 7 naar Drupal 8 lijkt een stuk groter dan het migreren van Drupal 6 naar Drupal 7.

Al met al zijn we erg enthousiast en we houden je op de hoogte van nieuwe ontwikkelingen.

SaveSave