1

I have seen in an email template, a token named [user:display-name]. Further noted that this token is not global, its value will only get rendered in email templates (correct me if I'm wrong).

How these specific tokens specially designed for only email tokens have been created?

In which file its logic is been written, I'm so curious, as the current user does not store any value of email receiver to whom email has to be sent. Then from where it picks the value of display name when current user is sending mail.

2

As Clive said, the tokens are generated from hook_token_info() and hook_tokens(). For the User entity, those hooks are implemented from the User module. Token values aren't available just for email templates, but for every function/method that uses the token service. For example, in a controller, I could use code similar to the following one.

$bubbleable_metadata = new BubbleableMetadata();
$build['#markup'] = $this->tokenService->replace('Tokens: [node:nid] [current-user:uid]', ['node' => $node], [], $bubbleable_metadata);
$bubbleable_metadata->applyTo($build);

As for getting the display name of a user account, that is easy: When user tokens are generated, user_tokens() gets a user object; calling User::getDisplayName() on that user object returns its display name.
See the code used from user_tokens(); in particular, see the following code. (Comments are mine.)

// Retrieves the user object passed to the hook.
$account = $data['user'];
// Generates the value for the display name token.
$replacements[$original] = $account
  ->getDisplayName();
if ($account->isAnonymous()) {
  $bubbleable_metadata->addCacheableDependency(\Drupal::config('user.settings'));
}

It is true there are user tokens available only for email templates, but that are generated from a callback used when replacing tokens in email templates. See user_mail() and user_mail_tokens().

  // user_mail()
  $token_service = \Drupal::token();
  $language_manager = \Drupal::languageManager();
  $langcode = $message['langcode'];
  $variables = ['user' => $params['account']];
  $language = $language_manager->getLanguage($params['account']
    ->getPreferredLangcode());
  $original_language = $language_manager->getConfigOverrideLanguage();
  $language_manager->setConfigOverrideLanguage($language);
  $mail_config = \Drupal::config('user.mail');
  $token_options = [
    'langcode' => $langcode,
    'callback' => 'user_mail_tokens',
    'clear' => TRUE,
  ];
  $message['subject'] .= PlainTextOutput::renderFromHtml($token_service
->replace($mail_config->get($key . '.subject'), $variables, $token_options));
  $message['body'][] = $token_service
    ->replace($mail_config->get($key . '.body'), $variables, $token_options);
function user_mail_tokens(&$replacements, $data, $options) {
  if (isset($data['user'])) {
    $replacements['[user:one-time-login-url]'] = user_pass_reset_url($data['user'], $options);
    $replacements['[user:cancel-url]'] = user_cancel_url($data['user'], $options);
  }
}

user_mail() says to Token::replace() that user_mail_tokens() must be called after all the tokens are generated, and user_mail_tokens() replaces [user:one-time-login-url] and [user:one-time-cancel-url] (not replaced from Token::replace()) with the right values.

Similar code can be used from any module to generate tokens that must be available only in specific context.

1

its value will only get rendered in email templates

Not true, that token is available any time the system gathers token for the user entity type.

How these specific tokens specially designed for only email tokens have been created?

As mentioned they're not just for emails, but they're defined in user_token_info(), and generated in user_tokens().

Then from where it picks the value of display name when current user is sending mail.

The token hook has access to the user account, so it simply uses $account->getDisplayName(); to populate the data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.