Het toevoegen van stylesheets (CSS) en JavaScript (JS) aan een Drupal 8-module
Deze documentatie is voor modules. Voor informatie over thema’s zie Stijlen (CSS) en JavaScript (JS) toevoegen aan een Drupal 8-thema.
In Drupal 8 worden stylesheets (CSS) en JavaScript (JS) geladen via hetzelfde systeem voor zowel modules (code) als thema’s: de assetbibliotheek. Assetbibliotheken kunnen één of meerdere CSS-bestanden, één of meerdere JS-bestanden en één of meerdere JS-instellingen bevatten.
Drupal gebruikt hierbij een belangrijk principe: middelen (CSS of JS) worden alleen geladen als u Drupal vertelt dat ze moeten worden geladen. Drupal laadt niet alle middelen (CSS/JS) op alle pagina’s, omdat dit de prestaties van de interface schaadt.
Verschillen met Drupal 7
Er zijn twee belangrijke verschillen met Drupal 7 voor ontwikkelaars:
1. Alleen de JavaScript die nodig is voor een specifieke pagina wordt aan die pagina toegevoegd. Standaard heeft Drupal geen JavaScript nodig op de meeste pagina’s die anonieme gebruikers kunnen zien. Dit betekent dat jQuery niet langer automatisch op alle pagina’s wordt geladen.
Dus als uw thema jQuery of een andere JavaScript nodig heeft (die ook in een assetbibliotheek is gedefinieerd), moet u Drupal hiervan op de hoogte stellen door een afhankelijkheid van de vereiste assetbibliotheek te declareren.
2. Het JavaScript-object Drupal.settings is vervangen door drupalSettings.
Proces
Belangrijkste stappen voor het laden van middelen (CSS / JS):
1. Sla de CSS of JS op in een bestand.
2. Definieer een “bibliotheek” die CSS- en JS-bestanden kan bevatten.
3. “Koppel” de bibliotheek aan een render-array in een hook.
Maar in het geval van thema’s is er een alternatief voor stap 3: thema’s kunnen een willekeurig aantal assetbibliotheken op alle pagina’s laden.
Bibliotheekdefinitie
Om één of meerdere bibliotheken (middelen) te definiëren, voegt u een bestand *.libraries.yml toe in de hoofdmap van uw modulemap (samen met het .info.yml-bestand). (Als uw module fluffiness heet, moet de bestandsnaam fluffiness.libraries.yml zijn). Elke “bibliotheek” in het bestand is een item dat de CSS- en JS-bestanden (middelen) specificeert, bijvoorbeeld:
Speciaal aandachtspunt voor Franstaligen: let erop dat u .libraries.yml correct schrijft! Niet .librairies.yml !! (bibliothèque betekent boekwinkel in het Frans …) anders zoekt u zich rot naar wat er mis is, want Drupal zal geen foutmelding geven bij een poging om een niet-bestaande bibliotheek te koppelen … ;)
cuddly-slider:
version: 1.x
css:
layout:
css/cuddly-slider-layout.css: {}
theme:
css/cuddly-slider-theme.css: {}
js:
js/cuddly-slider.js: {}
U kunt de sleutels ‘layout’ en ‘theme’ voor css opmerken, die niet bestaan voor js. Dit geeft aan tot welk type stijl het CSS-bestand behoort.
U kunt het gewicht van CSS instellen met 5 verschillende stijlniveaus:
- base: CSS reset/normalisatie plus styling van HTML-elementen. Sleutel krijgt gewicht CSS_BASE = -200
- layout: macrostructuur van de webpagina, inclusief gridsystemen. Sleutel krijgt gewicht CSS_LAYOUT = -100
- component: discrete, herbruikbare UI-elementen. Sleutel krijgt gewicht CSS_COMPONENT = 0
- state: stijlen die horen bij client-side statusveranderingen van componenten. Sleutel krijgt gewicht CSS_STATE = 100
- theme: puur visuele stijl (“look & feel”) van een component. Sleutel krijgt gewicht CSS_THEME = 200
Dit is gebaseerd op de SMACSS-standaard. Dus als u theme opgeeft, betekent dit dat het CSS-bestand stijlen bevat die puur uiterlijk zijn. Meer informatie hier. U mag geen andere sleutels gebruiken, anders krijgt u strikte waarschuwingen.
In dit voorbeeld bevindt het JavaScript cuddly-slider.js zich in de js-submap van uw module. U kunt JS ook van een externe URL laten komen, CSS-bestanden opnemen, en er zijn andere mogelijkheden. Zie CDN/externe bibliotheken voor details.
Vergeet niet dat Drupal 8 jQuery niet standaard op alle pagina’s laadt; Drupal 8 laadt alleen wat nodig is. Daarom moeten we aangeven dat de cuddly-slider-bibliotheek van onze module afhankelijk is van de bibliotheek die jQuery bevat. Dat is geen module of thema, maar de Drupal core: core/jquery is de afhankelijkheid die we moeten declareren. (Het is de extensienaam, gevolgd door een schuine streep, gevolgd door de bibliotheeknaam, dus als een andere bibliotheek afhankelijk wil zijn van onze cuddly-slider, moet deze afhankelijk zijn van fluffiness/cuddly-slider, omdat fluffiness de naam van onze module is.)
Om jQuery beschikbaar te maken voor js/cuddly-slider.js, werken we het bovenstaande voorbeeld dus bij:
cuddly-slider:
version: 1.x
css:
theme:
css/cuddly-slider.css: {}
js:
js/cuddly-slider.js: {}
dependencies:
- core/jquery
Zoals verwacht is de volgorde waarin CSS- en JS-middelen worden opgesomd ook de volgorde waarin ze worden geladen.
Standaard koppelt Drupal JS-middelen onderaan de pagina om veelvoorkomende problemen te voorkomen, zoals: blokkering van DOM-contentloading, toegang tot niet-gereed DOM-element uit jQuery-code, enz. Als u om welke reden dan ook JS-middelen in de <head> wilt toevoegen, kunt u de optie header gebruiken, bijvoorbeeld:
cuddly-slider:
version: 1.x
header: true
js:
js/cuddly-slider.js: {}
Nu zal js/cuddly-slider.js bovenaan de pagina worden toegevoegd.
Koppelen van bibliotheken aan pagina’s
Afhankelijk van welke middelen u wilt laden, kunt u de juiste bibliotheek op verschillende manieren koppelen. Sommige assetbibliotheken zijn nodig op alle pagina’s, andere zelden, en weer andere op de meeste maar niet alle pagina’s.
Het belangrijkste is echter dat we niet beslissen of we een bibliotheek koppelen op basis van welke pagina we ons bevinden (d.w.z. welke URL of route), maar op basis van de elementen die zichtbaar zijn op de pagina: als de pagina ‘#type’ => ‘table’, ‘#type’ => ‘dropbutton’ en ‘#type’ => ‘foobar’ bevat, dan laden we alleen de bibliotheken die bij elk van die #types horen.
Maar we zijn niet beperkt tot alleen “#type”: we kunnen ook een specifieke bibliotheek laden voor een specifieke instantie van een “#type”. In dat geval koppelen we deze gewoon aan de render-array van die instantie.
Het komt zelden voor dat er een goede reden is om een bepaalde asset op alle pagina’s te laden (bijv. een analytics-JavaScript dat paginaladingen bijhoudt), ongeacht de inhoud.
De subsecties hier tonen voorbeelden van hoe dit te doen.