Skip to content

Instantly share code, notes, and snippets.

@daggerhart
Created March 13, 2021 17:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daggerhart/ffb892ad7713d415e1694d33880f2c47 to your computer and use it in GitHub Desktop.
Save daggerhart/ffb892ad7713d415e1694d33880f2c47 to your computer and use it in GitHub Desktop.
Drupal tokens - hooks vs event_dispatcher
<?php
function mymodule_tokens_info_alter(&$info) {
// 1. New token type.
$info['types']['extra-details'] = [
'name' => t('Extra Details'),
'description' => t('Details for specific nodes.'),
'needs-data' => 'node',
];
// 2. Tokens for the new type.
$info['tokens']['extra-details']['example-1'] = [
'name' => t('Example 1'),
'description' => t('First example'),
];
$info['tokens']['extra-details']['example-2'] = [
'name' => t('Example 2'),
'description' => t('Another example'),
];
// 3. Add the new type to node.
$info['tokens']['node']['extra-details'] = [
'name' => t('Extra Details'),
'description' => t('Details for specific nodes.'),
'type' => 'extra-details',
];
}
function mymodule_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
$replacements = [];
if ($type == 'node') {
if ($details = \Drupal::token()->findWithPrefix($tokens, 'location-loans')) {
foreach ($details as $name => $original) {
switch ($name) {
case 'example-1':
$replacements[$original] = 'Great example!';
break;
case 'example-2':
$replacements[$original] = 'Another great example!';
break;
}
}
}
}
return $replacements;
}
<?php
namespace Drupal\mymodule\EventSubscriber;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Utility\Token as TokenService;
use Drupal\core_event_dispatcher\Event\Token\TokensInfoEvent;
use Drupal\core_event_dispatcher\Event\Token\TokensReplacementEvent;
use Drupal\core_event_dispatcher\ValueObject\Token;
use Drupal\core_event_dispatcher\ValueObject\TokenType;
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Class MyTokens.
*
* @package Drupal\mymodule\EventSubscriber
*/
class MyTokens implements EventSubscriberInterface {
use StringTranslationTrait;
/**
* Token service.
*
* @var \Drupal\Core\Utility\Token
*/
private $tokenService;
/**
* MyTokens constructor.
*/
public function __construct(TokenService $token_service) {
$this->tokenService = $token_service;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
return [
HookEventDispatcherInterface::TOKEN_INFO => 'tokenInfo',
HookEventDispatcherInterface::TOKEN_REPLACEMENT => 'tokenReplacement',
];
}
/**
* Provides new token types and tokens.
*
* @param \Drupal\core_event_dispatcher\Event\Token\TokensInfoEvent $event
* The token info event.
*/
public function tokenInfo(TokensInfoEvent $event): void {
// 1. New token type.
$my_token_type = TokenType::create(self::TOKEN_TYPE, 'Extra Details')
->setDescription('Details for specific nodes.')
->setNeedsData('node');
$event->addTokenType($my_token_type);
// 2. Tokens for the new type.
$event->addToken(Token::create($my_token_type->getType(), 'example-1', $this->t('Example 1'))->setDescription('Example 1'));
$event->addToken(Token::create($my_token_type->getType(), 'example-2', $this->t('Example 2'))->setDescription('Example 2'));
// 3. Add the new type to node.
$node_tokens = Token::create('node', $my_token_type->getType(), $my_token_type->getName());
$event->addToken($node_tokens);
}
/**
* Replace tokens.
*
* @param \Drupal\core_event_dispatcher\Event\Token\TokensReplacementEvent $event
* The token replacement event.
*/
public function tokenReplacement(TokensReplacementEvent $event): void {
if ($event->getType() !== 'node') {
return;
}
// Handle nested tokens.
$formats = $this->tokenService->findWithPrefix($event->getTokens(), 'extra-details');
foreach ($formats as $name => $original) {
// Rebuild the token's full name so we can test if this event is for the token, and later set its replacement.
$full_token_name = "extra-details:" . $token_name;
if ($event->forToken($event->getType(), $full_token_name)) {
switch ($name) {
case 'example-1':
$event->setReplacementValue('node', $full_token_name, 'Great example!');
break;
case 'example-2':
$event->setReplacementValue('node', $full_token_name, 'Another great example!');
break;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment