How to use Token API

Last updated on
19 April 2025

This documentation needs review. See "Help improve this page" in the sidebar.

Drupal's Token service can be accessed by calling either \Drupal::token() or \Drupal::service('token'). If you're working within a PHP class, implement via dependency injection where possible.

Calling the token service invokes an instance of the PHP class Drupal\Core\Utility\Token.
Most of the time you'll be calling its replace method to replace all available tokens within a piece of text. If you started in Drupal 7 or earlier, this will work similarly to its token_replace function.

A simple example below:

$result = \Drupal::token()->replace('<p>I looked at <em>[node:title]</em> on [date:short]</p>', ['node' => $node]);

The arguments supplied in this case are as follows:

  1. $markup = '<p>I looked at <em>[node:title]</em> on [date:short]</p>'
    The $markup argument is a HTML string containing tokens that are ready for replacement.

  2. $data = ['node' => $node]
    The $data argument contains contextual objects that supply information to each token. Since we've keyed a Node entity to 'node', the Token API can recognize it by the prefix and fetch information from the node entity to populate a replacement for [node:title].

So we might get output that looks like

<p>I looked at <em>Super easy vegetarian pasta bake</em> on 15 Apr 2025 - 21:46</p>

SECURITY NOTE: The value returned by Token::replace must be treated as unsafe, even if the $markup value supplied was known to be safe. In theory, an attacker could craft separate input strings and token values that may be completely safe to manage on their own; but when passed to Token::replace, they get combined into rendered output that compromises the site.

Other options

A more complex example might look like:

$result = \Drupal::token()->replace('<p>I looked at <em>[node:title]</em> on [date:short]</p>', ['node' => $node], ['langcode' => 'nl', 'callback' => 'my_custom_token_function', 'clear' => TRUE], $bubbleable_metadata);

The additional arguments supplied in this case:

  1. $options = ['langcode' => 'nl', 'callback' => 'my_custom_token_function', 'clear' => TRUE]
    The options array supplies additional information that controls the token replacement process. Supported options include:
    1. langcode = 'nl'
      The language code to be used when generated token values. In this case, we're trying to generate tokens in Dutch.
    2. callback = 'my_custom_token_function'
      This specifies a PHP callback function that will be used to post-process the array of token replacements after they are generated. A good example of this callback is user_mail_tokens, which gets called when generating tokens for email content by User module.
    3. clear = TRUE
      If set to TRUE, any piece of text within the $markup argument will be replaced with an empty string if a replacement value cannot be generated.
      If FALSE or unset, they will be left as they are.
  2. $bubbleable_metadata
    This can either be an object of class \Drupal\Core\Render\BubbleableMetadata or a NULL. Since this parameter is optional it defaults to NULL.
    This allows the token renderer to pass additional render metadata back, which might then be used to control caching among other behaviours.

Other Token API methods

The Token service contains a variety of other useful public methods.

How Token::replace works

When Token::replace is called, it invokes another protected method, Token::doReplace. This allows both Token::replace and Token::replacePlain methods to use the same internal behaviour.

Inside the Token::doReplace method, the following occurs.

  • The Token::scan method is called to scan for valid tokens in the text.
    • If there are none, return the original text without any changes.
  • Generate new bubbleable metadata if there is none.
  • Iterate over all the tokens that were found and generate replacements.
    • Once all replacements are generated, if $options['clear'] was set, fill the remainder of the replacements with an empty string.
  • Iterate over all the replacement strings.
    • If printing markup, ensure the replacement value either implements MarkupInterface or is wrapped as HtmlEscapedText.
    • If printing plain text, ensure the replacement value becomes a string.
  • Invoke $options['callback'], if set, to update token replacement values.
  • Split the tokens and replacement values into two arrays.
  • If we needed to create bubbleable metadata, apply the bubbleable metadata we just created to the current render context by rendering an empty array. This forces that metadata to bubble all the way to the top-level render context.
  • Perform str_replace on the original text, replacing all the tokens with all the values.

The Token::scan method runs a regular expression match across the text to see if there are any token-like strings in the text.

Help improve this page

Page status: Needs review

You can: