In this tutorial, we'll learn how to create an automatic node title using a custom event and event subscriber in Drupal 9. This can be helpful when you want to generate titles for specific content types programmatically.
First, create a custom module if you haven't already. For this example, let's name the module auto_title.
Inside the src/Event folder of your custom module, create a new PHP file called AutoTitleEvent.php. Add the following code to define your custom event:
namespace Drupal\auto_title\Event;
use Drupal\node\NodeInterface;
use Symfony\Contracts\EventDispatcher\Event;
class AutoTitleEvent extends Event {
const AUTO_TITLE = 'auto_title.auto_title_event';
protected $node;
public function __construct(NodeInterface $node) {
$this->node = $node;
}
public function getNode() {
return $this->node;
}
}
In the src/EventSubscriber folder of your custom module, create a new PHP file called AutoTitleSubscriber.php. Add the following code to define the event subscriber:
namespace Drupal\auto_title\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\auto_title\Event\AutoTitleEvent;
class AutoTitleSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents() {
$events[AutoTitleEvent::AUTO_TITLE][] = 'onAutoTitle';
return $events;
}
public function onAutoTitle(AutoTitleEvent $event) {
$node = $event->getNode();
if ($node->bundle() == 'your_content_type') {
// Generate your custom title here.
$title = 'Custom Title - ' . date('Y-m-d H:i:s');
// Set the node title.
$node->setTitle($title);
}
}
}
Replace 'your_content_type' with the machine name of the content type you want to target.
In your custom module's auto_title.services.yml file, register the event subscriber:
services:
auto_title.auto_title_subscriber:
class: Drupal\auto_title\EventSubscriber\AutoTitleSubscriber
tags:
- { name: event_subscriber }
Implement hook_entity_presave in your custom module's .module file and dispatch the custom event:
use Drupal\auto_title\Event\AutoTitleEvent;
/**
* Implements hook_entity_presave().
*/
function auto_title_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
if ($entity->getEntityTypeId() == 'node') {
$event_dispatcher = \Drupal::service('event_dispatcher');
$auto_title_event = new AutoTitleEvent($entity);
$event_dispatcher->dispatch($auto_title_event, AutoTitleEvent::AUTO_TITLE);
}
}
After making changes to your custom module, clear the cache to ensure your changes take effect:
drush cr
By following these steps, you've created a custom event and an event subscriber to automatically set the node