Dit is het derde en laatste deel van mijn reeks ‘Headless Drupal & Node.js’. Voorgaande delen:
- Deel 1: het opzetten van een RESTful Web Service in Drupal 8
- Deel 2: een introductie in Node.js
In dit laatste deel laat ik zien:
- Installatie en introductie Express JS in Node.js.
- Routes en dynamische templates met EJS in Express JS.
- Koppelen van de data uit de RESTful Drupal web service.
1) Installatie en introductie Express JS in Node.js
Zoals in deel 2 beschreven, Node.js op zichzelf is een minimalistisch opgezette webserver en niet primair bedoeld voor websites. Wanneer je het wilt inzetten voor websites dan helpt Express JS je hierin: het is een “Fast, unopinionated, minimalist web framework for Node.js”.
Het bevat een aantal robuste features om web -en mobiele applicatie te ontwikkelen, tevens voor het bouwen van API’s kan je het inzetten. Express JS geeft Node.js een structuur welke niet aanwezig is als je Node.js op zichzelf gebruikt. Het faciliteert in onder andere:
- Templating;
- Routing;
- MVC gebaseerd werken.
Templating
Express JS bevat twee templating engines: de standaard is Jade, de tweede is EJS. Jade is ‘whitespace based’ en wordt als volgt gebruikt:
EJS is meer volledige HTML, wij hebben gekozen voor EJS:
Routing
Ook bevat Express JS een routing systeem, wat ervoor zorgt dat de URL de inhoud van de pagina kan beïnvloeden, zoals gewenst voor dynamische websites.
MVC
Express JS is MVC gebaseerd: Model View Controler, een moderne manier om web applicaties te bouwen. Het zorgt ervoor dat je je website modulair op kunt zetten, in plaats van het schrijven van verschillende pagina’s maak je:
- Model: de data die je applicatie gaat gebruiken.
- View: hier wordt de data in gegoten - het template middels EJS.
- Controller: het Javascript dat de data en het template dynamisch opbouwt.
Express JS lijkt in eerste instantie wellicht apart om mee te werken, maar zodra je er aan gewend bent zal het lastig zijn om terug te gaan naar een ouderwetse manier.
Installatie Express JS
In deel twee zag je de installatie van modules met NPM. Je kunt NPM modules op twee manieren installeren:
- Als globale applicatie;
- Per project.
Afhankelijk van je project(en) kan je kiezen voor een van deze twee methodes. Express JS installeer ik zowel globaal als per project.
Globale installatie
De globale versie hebben we nodig, omdat die meteen Command Line Interface Tools (CLI’s) installeert die we nodig hebben. Type in:
npm install -g express
Wanneer je een error krijgt, installeert dan als super user: sudo npm install -g express.
Wanneer je nu entert: express -- version zou je een versie nummer moeten zien:
Lokale installatie
Enter nu npm install express --save:
Express JS wordt als dependency aan je project toegevoegd, wat je terug ziet in de package.json file:
Express JS is nu geïnstalleerd, we kunnen starten met een ‘Hello Express’.
‘Hello Express’
We hebben aangegeven dat hellotest.js het startpunt. Die file open ik en schrijf volgende code:
var express = require('express');
==> Maak de variabel ‘express’ aan en definieer dat je de library ‘express’ wilt gebruiken.
var app = express();
==> Maak de variabele ‘app’ aan voor de applicatie die we met Express JS gaan maken. Door deze applicatie namespacing kunnen we nu gebruik maken van methods die Express ons geeft. opgenomen in deze globale variabele ‘app’.
app.get ('/', function(req, res){
res.send('Hello Express');
});
==> Dit is de routing techniek, dit eenvoudige voorbeeld zorgt ervoor dat een request op in de root (homepage van je website) wordt beantwoord met een tekst.
Zoals je in deel twee kan lezen, moest je in Node.js ook het mime-type hier definiëren. Omdat Express JS ervan uit gaat dat je met een web protocol werkt, is dat niet meer nodig.
var server = app.listen (2000, function(){
console.log('Waiting for you on port 2000');
});
==> Opzetten van de server op poort 2000.
Om deze test te draaien enter ik ‘node hellotest.js’ in mijn terminal:
Vervolgens browse naar http://localhost:2000 en zou je volgende scherm moeten zien:
Zoals je ziet is het soortgelijk aan het voorbeeld in Node.js zoals in deel twee, maar we gebruiken Express JS methods die de boel vereenvoudigen voor ons; bijvoorbeeld de routing in ons eenvoudige voorbeeld. Voor een compleet overzicht van alle methods, properties en events, zie de Express JS API
Routes in Express JS
Routes zorgen ervoor dat je dynamisch content kunt uitserveren gebaseerd op URL. Express JS is goed in het facilteren van benodigde routes, zie het als Drupal’s hook_menu. Ik voeg als volgt een tweede route toe:
Als ik dan in mijn browser naar /about-us ga:
Routes met variabele
Het is ook mogelijk om informatie via routes naar de applicatie te sturen. De informatie wordt geplaatst in een parameters variabele binnen het request object. Die variabelen worden gemapt naar -en zijn beschikbaar in de request paramaters array. Dit kan je als volgt doen:
var name = req.params.name;
==> Plaatst alles wat achter /about/ staat in een variable ‘name’. Dit wordt gedaan via de request parameters array (req.params) van Express JS: die plaatst een object ‘name’ in de array en stuurt dat naar de local variable ‘name’.
Vervolgens print ik ‘name’ binnen <h1> tags, waardoor je dynamische output op basis van URL genereert:
Je kunt meerdere variables opnemen:
Dit resulteert in:
Als laatste wil ik graag de 404 routeren, dat kan bijvoorbeeld op deze manier:
2) Routes en dynamische templates met EJS in Express JS
Tot nu toe hebben we res.send gebruikt, maar een betere manier is om dit via templates uit te serveren. Zoals hierboven beschreven gebruikt Express Jade als standaard. Wij gebruiken EJS:
Binnen EJS kan je standaard HTML gebruiken en daarin tags opnemen, die de dynamische content genereren.
Installatie EJS
Enter in je terminal: npm install ejs --save
Je zou nu in package.json de dependency moeten zien:
Nu EJS geïnstalleerd is, kan je hem activeren in de applicatie met
app.set('view engine','ejs');
Vervolgens maken we een map ‘views’ aan, waar we een standaard html document ‘default.ejs’ in plaatsen:
Nu kunnen we dit template aanroepen middels res.render(). Toegepast op de homepage:
Express JS weet dat hij in de folder ‘views’ moet kijken voor de template-file, dat is de standaard. Je kunt je eigen folder definieren met:
app.set(‘views’, __dirname + ‘/YOURFOLDER’);
__dirname is een global die ook op andere plaatsen kunt gebruiken.
Data meesturen naar het EJS template
Je kunt een extra object meesturen naar je template, dat doe je als volgt:
Deze kan je in het EJS template als volgt printen:
Waardoor je in je browser dit te zien krijgt:
Je kunt ook Javascript gebruiken in de EJS templates, gebruik dan <% jouw kick-arse Javascript %> in plaats van <%= jouw printbare variabele %>.
Als laatste wellicht goed om te weten: templates worden ook wel ‘views’ genoemd, data wordt ook wel ‘the model’ genoemd. Als je the ‘modal’ samen gaat voegen met een ‘view’, krijg je dynamische websites.
Routes en templates in Express JS structureren
Wanneer je veel routes definieert dan is het handig die in een aparte file te plaatsen, buiten de ‘main app’ file. Zo houd je alles beter georganiseerd, dit is relatief eenvoudig te doen:
- Maak een nieuwe map aan: ‘routes’;
- Plaats daar een nieuwe file in ‘index.js’;
- Importeer de express module en definieer de ‘router’ variabele;
- Verplaats de routing code naar deze nieuwe file;
- ‘Exporteer’ de routes:
Wijzig vervolgens de main-app file, ‘hellotest.js’ in ons geval:
- Definieer de ‘routes’ variabele,
- Voeg toe:
app.use (‘/’, routes):
Alrighty, nu zijn je routes en je views afgesplitst en netjes in aparte folder georganiseerd waardoor je applicatie compacter, overzichtelijker en beter beheerbaar is geworden. De basis staat nu, als laatste gaan we de data uit de Drupal RESTful API inladen.
3) Drupal RESTful API data integreren in Node.js
We hebben nu de Node.js basis staan met behulp van Express JS. Ook hebben we de Drupal data al beschikbaar via een JSON API, zie ook deel 1. Nu wordt het tijd voor de magie: het koppelen van deze twee waardoor een dynamische website het daglicht ziet.
Installatie npm module request
Om externe data te importeren heb je als eerste een extra npm module nodig: ‘Request’. Dit is een populaire module, die het makkelijk maakt om http calls uit te voeren en hierin data uit te wisselen. Installeer deze module: enter ‘npm install request’ in je terminal (‘sudo’ prependen als je een error krijgt):
Nu de module is geïnstalleerd moeten we hem importeren in ons project met
var request = require(“request”);
Het importeren van de json data uit de Drupal web service
De module is nu geïnstalleerd in onze Node.js applicatie, we kunnen gebruik maken van zijn functies. Onderstaand scriptje gebruiken we om de blog data uit te lezen:
- Op regel 5 maak ik een variabele aan, waarin de url van de Drupal json export opgenomen wordt.
- Op regel 13 - 32 wordt het json object uitgelezen: de juiste velden worden opgenomen in een array die wordt geplaatst in een globale variabele ‘app.locals.blogsdata’ .
app.locals.XYZ wordt binnen Node.js gebruikt om globale variabele in op te nemen, deze variabelen zijn beschikbaar in alle templates. Voor het gemak plaats ik hem in een globale, omdat de footer van onze website ook een rijtje blogs nodig heeft die op elke pagina zichtbaar wordt.
Alle blog data uit de Drupal API is nu dus beschikbaar in de globale variabele app.locals.blogsdata.
Het uitserveren van de Drupal data in een dynamisch EJS template
Om te starten hebben we de blog overview pagina 5 laatste blogs worden getoond. Die kunnen we als volgt opbouwen:
Maak de basis HTML pagina aan en include daarin het content deel:
Maak vervolgens een nieuwe map in de map ‘views’ aan genaamd ‘content’ en plaats een nieuwe file ‘blog-overview-articles.ejs’, waarin de blog-data uit de variabele app.locals.blogsdata wordt geprint met behulp van Javascript:
Even ter herinnering, dit is het json object (zie ook deel 1):
We hebben nu de blog overzicht pagina geconstrueerd in Node.js, waarbij data uit de Drupal API ingeladen wordt. Het resultaat kan je hier zien.
De Drupal data integreren op de blog detail pagina
De url van de blog pagina is als volgt opgebouwd: ‘/blog/blog-item-titel’. De inhoud van de pagina hangt af van deze variabele titel. Hierboven zag je hoe we om kunnen gaan met variabelen via de url. We routeren de data voor het als volgt:
We checken hierin de huidige url en matchen hem op de (unieke) url in het json object. Wanneer die gevonden is, wordt bijbehorende data in een array gezet welke wordt meegegeven naar het template.
Wrap up
Ok, that’s it voor deze driedelige reeks Drupal & Node.js. Uiteraard is dit maar een bondige introductie in Drupal Web services en Node.js.
We hebben alleen de ‘GET’ geraakt van de Drupal RESTful api. API stuff als POST, PUT, DELETE, OPTIONS zijn ook mogelijk met Drupal 8 maar nog niet nodig geweest in onze website.
Ook hebben we pas de oppervlakte geraakt van Node.js en Express JS, maar voldoende om een dynamische website te bouwen.
Verdere verdieping op uitzonderingen die we tegenkwamen in een volgend Drupal API blog, so stay tuned!