9.11. Drupal Entity API. Aangepast entiteitstype maken. Entiteitstype genereren met Drupal Console.
We hebben al kennisgemaakt met de Form API en de Fields API en we weten hoe gegevens in Drupal in de database terechtkomen. Laten we nu kijken naar de basis van alle Drupal-sites: de Entity API.
Je hebt waarschijnlijk al gemerkt dat velden niet op zichzelf bestaan, maar zijn “gekoppeld” aan entiteiten: nodes, blokken, taxonomietermen, views, enzovoort. Je kunt bundel-entiteiten maken, zoals inhoudstypen, bloktypen en taxonomiewoordenboeken. Maar wat als je een volledig nieuw entiteitstype met eigen bundels wilt maken? In dat geval heb je de Entity API nodig om een nieuwe entiteit te creëren.
Ik heb alle code toegevoegd op GitHub in de module drupalbook_product. Je kunt de module downloaden en aan je website toevoegen:
https://github.com/levmyshkin/drupalbook8
De eenvoudigste manier om nieuwe entiteitstypen te maken is via Drupal Console, omdat daarvoor slechts één commando hoeft te worden uitgevoerd.
Je zult niet vaak nieuwe entiteitstypen hoeven aan te maken. De meeste kleine en middelgrote projecten gebruiken contrib-modules als basis — bijvoorbeeld Commerce voor webwinkels:
https://www.drupal.org/project/commerce
Als je van plan bent een eigen plug-inmodule te schrijven, kan het nodig zijn om een nieuw entiteitstype te maken. Vaak kun je echter tussen bestaande Drupal-modules al een module vinden met vergelijkbare functionaliteit, die je eventueel kunt uitbreiden of aanpassen aan je behoeften.
In dit artikel bekijken we de Entity API en maken we ons eigen type Product-entiteit, dat zal dienen als basis voor een kleine aangepaste catalogus of winkel. Als je echt een volledige webshop wilt bouwen, raad ik ten zeerste aan om Commerce te gebruiken, omdat dat je (en je klanten) enorm veel tijd zal besparen.
Wanneer je een nieuw entiteitstype wilt maken, komt vaak de vraag op: waarom niet gewoon een nieuw inhoudstype “Product” aanmaken en dat gebruiken voor een catalogus? Dat kan zeker voor een kleine catalogus met producten die via Views worden weergegeven en gefilterd op prijs of voorraad. Maar zodra het aantal producten in de duizenden loopt, wordt het voor een beheerder onhandig om producten te zoeken via de standaardinhoudspagina. De beheerder wil waarschijnlijk filters toevoegen voor artikelnummer, categorie, kleur, naam en andere kenmerken op de pagina:
/admin/content
Dat zou te druk worden en het werken met andere inhoudstypen zoals Nieuws, Artikelen, Evenementen en Pagina’s bemoeilijken. In zulke gevallen is het beter een apart Product-entiteitstype te maken met een eigen beheerinterface en instellingen.
Laten we beginnen met het aanmaken van een apart type Product-entiteit. Voordat je het commando uitvoert om een entiteitstype te genereren, raad ik ten zeerste aan om een back-up van de site te maken — ten minste van de database. Het aanmaken van een entiteitstype genereert configuratiebestanden die in de database worden opgeslagen, en als er iets misgaat (bijvoorbeeld een incomplete configuratie zonder de bijbehorende bestanden in de module), kan dat de site breken. Maak dus eerst een back-up!
We maken nu een nieuwe module aan, wat ook kan via de Drupal Console:
drupal generate:module
https://hechoendrupal.gitbooks.io/drupal-console/en/commands/generate-module.html
$ vendor/bin/drupal generate:module
// Welcome to the Drupal module generator
Enter the new module name:
> Drupalbook Product
Enter the module machine name [drupalbook_product]:
>
Enter the module Path [modules/custom]:
>
Enter module description [My Awesome Module]:
> Products catalog
Enter package name [Custom]:
>
Enter Drupal Core version [8.x]:
>
Do you want to generate a .module file? (yes/no) [yes]:
> no
Define module as feature (yes/no) [no]:
> no
Do you want to add a composer.json file to your module? (yes/no) [yes]:
> no
Would you like to add module dependencies? (yes/no) [no]:
> no
Do you want to generate a unit test class? (yes/no) [yes]:
> no
Do you want to generate a themeable template? (yes/no) [yes]:
> no
Do you want proceed with the operation? (yes/no) [yes]:
> yes
Generated or updated files
Generation path: /home/laptop/projects/drupalbook
1 - /modules/custom/drupalbook_product/drupalbook_product.info.yml
Generated lines: "5"
Of maak gewoon handmatig een module aan met het bestand drupalbook_product.info.yml:
name: 'drupalbook_product'
type: module
description: 'Products catalog'
core: 8.x
package: 'Drupalbook'
Nu kunnen we het Product-entiteitstype genereren.
https://hechoendrupal.gitbooks.io/drupal-console/en/commands/generate-entity-content.html
$ vendor/bin/drupal generate:entity:content
// Welcome to the Drupal Content Entity generator
Enter the module name [admin_toolbar]:
> drupalbook_product
Enter the class of your new content entity [DefaultEntity]:
> DrupalbookProductEntity
Enter the machine name of your new content entity [drupalbook_product_entity]:
>
Enter the label of your new content entity [Drupalbook product entity]:
> Product
Enter the base-path for the content entity routes [/admin/structure]:
>
Do you want this (content) entity to have bundles? (yes/no) [no]:
> yes
Is your entity translatable? (yes/no) [yes]:
> yes
Is your entity revisionable? (yes/no) [yes]:
> no
Generated or updated files
Generation path: /home/laptop/projects/drupalbook
...
Generated lines: "1060"
Nu de module is gegenereerd, kun je deze inschakelen zodat het nieuwe entiteitstype op de site verschijnt:
Tijdens het genereren van de entiteit vraagt de Drupal Console hoe het entiteitstype moet worden ingesteld.
Enter the class of your new content entity [DefaultEntity]:
De naam van de PHP-klasse voor onze entiteit; het is aanbevolen om “Entity” aan het einde van de naam toe te voegen.
Enter the machine name of your new content entity [drupalbook_product_entity]:
De machinenaam wordt automatisch voorgesteld op basis van de klassenaam; druk op Enter om de voorgestelde naam te gebruiken.
Enter the base-path for the content entity routes [/admin/structure]:
Je entiteitstypen krijgen hun eigen pagina voor CRUD-bewerkingen:
De standaardweergave van de productpagina is vrij eenvoudig, maar deze kun je later verbeteren of via Views aanpassen:
Om een nieuwe entiteit te maken, moet je eerst een bundel van het type Product aanmaken. We hebben gekozen voor een “bundlable” entiteit:
Do you want this (content) entity to have bundles? (yes/no):
Daarom maken we een nieuw type product aan. Dit is nodig om verschillende velden te kunnen definiëren zoals Gewicht, Afmeting, Kleur en andere kenmerken. Bijvoorbeeld: monitoren hebben een schermafmeting, en schoenen hebben een schoenmaat.
Laten we een nieuw producttype aanmaken — Kleding:
Nu kun je de velden voor het nieuwe producttype configureren:
We hebben in ieder geval een prijsveld nodig.
Laten we een paar producten aanmaken en in de database kijken. Daarin vinden we de tabel drupalbook_product_entity, waarin de UUID’s van onze producten worden opgeslagen:
Er is ook een tweede tabel drupalbook_product_entity_field_data, waarin de eigenschappen (properties) van de entiteit worden opgeslagen. Dit zijn speciale velden die direct in tabellen worden opgeslagen, zoals de naam (Entity label, bijvoorbeeld de titel van een node), omdat deze niet per revisie veranderen.
Als je velden toevoegt, worden voor elk veld twee tabellen aangemaakt, omdat we hebben gekozen voor revisies:
Is your entity revisionable? (yes/no) [yes]
Ik denk dat je nu begrijpt hoe je nieuwe entiteitstypen kunt aanmaken. In de volgende artikelen zullen we de mogelijkheden van onze aangepaste catalogus/winkel verder uitbreiden.
Ik heb alle code toegevoegd op GitHub in de module drupalbook_product; je kunt deze downloaden en aan je website toevoegen: