logo

Dodatni tipovi blokova (EBT) - Novo iskustvo rada sa Layout Builder-om❗

Dodatni tipovi blokova (EBT) – stilizovani, prilagodljivi tipovi blokova: slajdšouvi, kartice sa tabovima, kartice, akordeoni i mnogi drugi. Ugrađena podešavanja za pozadinu, DOM Box, javascript dodatke. Iskusite budućnost kreiranja rasporeda već danas.

Demo EBT moduli Preuzmite EBT module

❗Dodatni tipovi pasusa (EPT) – Novo iskustvo rada sa pasusima

Dodatni tipovi pasusa (EPT) – analogni skup modula zasnovan na pasusima.

Demo EPT moduli Preuzmite EPT module

Scroll
27/05/2025, by Ivan

U prethodnim člancima već smo se susreli sa kukicama (hook-ovima). U ovom članku ćemo detaljnije pogledati kukice koje vam pomažu da radite sa entitetima.

U ovom članku možete pročitati uopšteno šta su kukice i zašto su potrebne:

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

Kukice koristimo da dodamo sopstveni kod koji će se pokrenuti na određene događaje vezane za entitete: dodavanje, brisanje, izmena.

Sve Drupal kukice možete videti na ovoj stranici:

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

Dodirnućemo samo deo njih, one koje se najčešće koriste u prilagođenim modulima za rad sa sadržajem.

Sve kodove sam dodao na github u modul drupalbook_examples, možete skinuti modul i dodati ga na svoj sajt:

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 . ' by ' . date('d-m-Y');
  }
}

Hook_entity_presave() se pokreće svaki put kada se entitet sačuva.

Nije potrebno pozivati $entity->save() unutar hook-a jer će objekat entiteta biti modifikovan pre samog čuvanja. U ovom primeru dodajemo trenutni datum čuvanja čvora (node) na naslov članka. Ako izmenite članak narednog dana, novi datum će ponovo biti dodat. Ako ne uklonite datum iz naslova pre čuvanja, naslov će se sa svakim čuvanjem sve više povećavati. Najčešće proveravamo postojanje određenih vrednosti u poljima entiteta prilikom čuvanja ili možemo poslati email sa obaveštenjem o promeni članka.

Obratite pažnju da prvo proveravamo željeni tip entiteta, jer kod u hook_entity_presave() radi za sve entitete: sadržaj, blokove, komentare, taksonomijske termine. Takođe proveravamo i bundle (tip) nodova koji su nam potrebni.

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'       => 'New page created: ' . $entity->title->value,
    ]);
    $node->save();
  }
}

Hook_entity_insert() se poziva kada se doda novi entitet. Na primer, prilikom kreiranja nove stranice na sajtu, kreiraće se i članak. Ako imate prethodni hook, datum će biti dodat u naslov kreiranog članka.

Treba napomenuti razliku između hook_entity_insert() i hook_entity_presave() hook-ova. Hook_entity_insert() se pokreće samo jednom prilikom dodavanja entiteta i ne menja vrednosti polja entiteta. Dakle, ako ubacite kod iz prvog hook-a u drugi, taj kod neće raditi:

/**
 * 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 . ' by ' . date('d-m-Y');
  }
}

Naravno, možete postići čuvanje vrednosti nod-a:

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();
  }
}

Ali ovo nije preporučljivo, najbolje je koristiti hook_entity_presave() za promenu entiteta pre čuvanja, a hook_entity_insert() za promenu drugih entiteta ili drugih akcija.

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('Page has been changed: ' . $entity->title->value);
  }
}

Hook_entity_update() se pokreće svaki put kada se entitet izmeni. Ovde treba odmah naglasiti da nije preporučljivo menjati polja $entity objekta u ovom hook-u, jer on, kao i hook_entity_insert(), služi za pozivanje akcija koje nisu vezane za podatke polja entiteta. Ovaj hook treba koristiti za logovanje, slanje poruka ili druge akcije.

Takođe, nemojte pozivati $entity->save() unutar ovog hook-a da ne bi došlo do beskonačne petlje. Ako ipak pozovete, vodite računa da se ne desi loop.

hook_entity_delete()

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

Još jedan hook za logovanje i izvršavanje akcija nakon brisanja entiteta.

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();
  }
}

?>

U ovom primeru blokiramo pristup člancima za sve korisnike koji nemaju ulogu administratora. Naravno, ako su vam dovoljna standardna podešavanja prava za uloge za kontrolu pristupa sadržaju, onda je bolje koristiti podešavanja dozvola.

Hook_entity_access() se koristi za fleksibilno podešavanje pristupa sadržaju, na primer po rasporedu, ispunjavanju određenih uslova po korisničkim poenima, rangi, nivou korisnika i slično. Ako ograničavate pristup određenom sadržaju putem ovog hook-a, time prepisujete standardna prava pristupa, što može zbuniti drugog programera koji bude nastavljao rad na projektu.

Odatle dolazi glavni minus kukica — nevidljivost izvršavanja koda treće strane. Ako ne znamo za postojanje modula sa implementiranim hook-ovima, biće nam misterija zašto se naslov članka menja prilikom čuvanja.

Naravno, znamo da kukice postoje, te svaki put kada naiđete na slično ponašanje, na primer prilikom izmene noda, moraćete da pretražujete ceo projekat po imenu hook_entity_presave ili hook_entity_update. Programeri često prate kodni vodič i ostavljaju komentare "Implements hook_entity_presave()", tako da se može lako pronaći po imenu hook-a, ali ne treba zaboraviti da ne svi programeri to rade, naročito ako ste dobili projekat od poslednjeg tima koji nije radio dobar posao.

Pregledali smo samo nekoliko hook-ova, ali mislim da sada imate osnovno razumevanje gde i kako koristiti kukice. Što više budete radili sa Drupalom, to ćete češće imati potrebu za pisanjem sopstvenog koda. Ako vam se neki hook čini kao dobro mesto za dodavanje koda, slobodno ga implementirajte u svom prilagođenom modulu.