logo

Extra Block Types (EBT) - Nieuwe Layout Builder ervaringâť—

Extra Block Types (EBT) - gestileerde, aanpasbare bloktypes: Slideshows, Tabs, Cards, Accordions en vele andere. Ingebouwde instellingen voor achtergrond, DOM Box, javascript-plugins. Ervaar vandaag al de toekomst van layout building.

Demo EBT-modules Download EBT-modules

âť—Extra Paragraph Types (EPT) - Nieuwe Paragraphs ervaring

Extra Paragraph Types (EPT) - analoge op paragrafen gebaseerde set modules.

Demo EPT-modules Download EPT-modules

Scroll
16/10/2025, by Ivan

In eerdere artikelen zijn we al in aanraking gekomen met hooks. In dit artikel bekijken we uitgebreider de hooks die helpen bij het werken met entiteiten.

In dit artikel kun je in het algemeen lezen wat hooks zijn en waarom ze nodig zijn:

http://drupalbook.org/drupal/92-what-hook-drupal-8

We zullen hooks gebruiken om aangepaste code toe te voegen die wordt uitgevoerd bij bepaalde gebeurtenissen die met entiteiten te maken hebben: toevoegen, verwijderen, bijwerken.

Je kunt alle Drupal-hooks bekijken op deze pagina:

https://api.drupal.org/api/drupal/core!core.api.php/group/hooks/8.2.x

We behandelen slechts een deel van de hooks — de meest gebruikte in aangepaste modules die met inhoud werken.

Ik heb alle code toegevoegd aan de module drupalbook_examples op GitHub. Je kunt de module downloaden en aan je site toevoegen:

https://github.com/levmyshkin/drupalbook8

hook_entity_presave()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_presave/8.6.x

/**
 * Implements hook_entity_presave().
 */
function drupalbook_examples_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'article') {
    $entity->title->value = $entity->title->value . ' door ' . date('d-m-Y');
  }
}

hook_entity_presave() wordt aangeroepen telkens wanneer een entiteit wordt opgeslagen.

Je hoeft binnen deze hook geen $entity->save() aan te roepen, omdat het entiteitsobject vóór het opslaan wordt gewijzigd. In dit voorbeeld voegen we aan de titel van een artikel de datum toe waarop de node wordt opgeslagen. Als we het artikel de volgende dag bijwerken, wordt de nieuwe datum er opnieuw aan toegevoegd. Als je de vorige datum niet verwijdert vóór het opslaan, wordt de titel telkens langer. Meestal gebruiken we deze hook om te controleren of bepaalde velden zijn ingevuld of om bijvoorbeeld een e-mailmelding te verzenden wanneer een artikel wordt gewijzigd.

Let erop dat we eerst het entiteitstype controleren, want de code in hook_entity_presave() werkt voor alle entiteiten: inhoud, blokken, reacties, taxonomietermen. We controleren ook het gewenste bundletype van de node.

hook_entity_insert()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_insert/8.6.x

/**
 * Implements hook_entity_insert().
 */
function drupalbook_examples_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'page') {
    $node = Node::create([
      'type'        => 'article',
      'title'       => 'Nieuwe pagina aangemaakt: ' . $entity->title->value,
    ]);
    $node->save();
  }
}

hook_entity_insert() wordt aangeroepen wanneer een nieuwe entiteit wordt toegevoegd. In dit voorbeeld wordt bij het aanmaken van een nieuwe pagina automatisch een artikel aangemaakt. Als je de vorige hook ook hebt geĂŻmplementeerd, wordt de datum toegevoegd aan de titel van dat artikel. 

Er is een belangrijk verschil tussen hook_entity_insert() en hook_entity_presave()hook_entity_insert() wordt slechts één keer uitgevoerd bij het toevoegen van een entiteit en verandert geen veldwaarden. Als je dus de code uit de eerste hook hier zou plaatsen, zou die niet werken:

/**
 * Implements hook_entity_insert().
 */
function drupalbook_examples_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'article') {
    $entity->title->value = $entity->title->value . ' door ' . date('d-m-Y');
  }
}

Je kunt de node natuurlijk opnieuw opslaan:

function your_module_entity_insert(Drupal\Core\Entity\EntityInterface $entity){
  if ($entity->getType() == 'article') {
    drupal_register_shutdown_function('_your_module_post_insert', $entity);
  }
}
 
function _your_module_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity) {
      $entity->save();
  }
}

Maar dit wordt afgeraden. Gebruik hook_entity_presave() om het entiteitsobject zelf te wijzigen bij het opslaan, en hook_entity_insert() voor aanvullende acties of het wijzigen van andere entiteiten.

hook_entity_update()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_update/8.2.x

/**
 * Implements hook_entity_update().
 */
function drupalbook_examples_entity_update(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'page') {
    \Drupal::messenger()->addMessage('Pagina is gewijzigd: ' . $entity->title->value);
  }
}

hook_entity_update() wordt uitgevoerd telkens wanneer een entiteit wordt bijgewerkt. Net als bij hook_entity_insert() moet je binnen deze hook geen velden van de entiteit aanpassen. Gebruik deze hook voor logging, meldingen of andere acties die niet direct de veldwaarden wijzigen. 

Voer geen $entity->save() uit binnen deze hook om te voorkomen dat hook_entity_update() opnieuw wordt aangeroepen en een oneindige lus veroorzaakt.

hook_entity_delete()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_delete/8.6.x

Een andere hook die handig is voor logging of het uitvoeren van acties nadat entiteiten zijn verwijderd.

hook_entity_access()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_access/8.2.x

<?php

use Drupal\Core\Access\AccessResult;
 
/**
 * Implements hook_entity_access().
 */
function drupalbook_examples_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'article' && $operation == 'view' && in_array('administrator', $account->getRoles())) {
    AccessResult::forbidden();
  }
}
?>

In dit voorbeeld blokkeren we de toegang tot artikelen voor alle gebruikers die niet de rol administrator hebben. Als de standaardmachtigingen voldoende zijn om toegang tot inhoud te regelen, gebruik die dan. hook_entity_access() is bedoeld voor meer geavanceerde toegangslogica, bijvoorbeeld gebaseerd op schema’s, gebruikerspunten, karma of ervaringsniveaus. 

Als je toegang tot inhoud via deze hook aanpast zonder duidelijke documentatie, kan dat later verwarring veroorzaken voor andere ontwikkelaars. Een nadeel van hooks is namelijk dat hun uitvoering niet altijd direct zichtbaar is. Als je bijvoorbeeld niet weet dat een module een hook bevat, is het moeilijk te begrijpen waarom de titel van een artikel automatisch wordt gewijzigd bij het opslaan. Daarom moet je bij onverwacht gedrag (zoals wijzigingen bij opslaan of bijwerken) zoeken naar entity_presave of entity_update in de projectcode. 

We hebben slechts een paar hooks behandeld, maar je zou nu een goed beeld moeten hebben van hoe en wanneer je ze kunt gebruiken. Hoe meer je met Drupal werkt, hoe vaker je aangepaste code zult moeten schrijven. Als een van deze hooks een geschikte plek lijkt om code toe te voegen, kun je hem gerust implementeren in je eigen module.