Edit: I guess it has something to do with the info part:

function mymodule_token_info() {
  $info = array();
  $info['types']['embed'] = array(
    'name' => t('Embed'),
    'description' => t('Embed entities via token.'),
  $info['tokens']['embed'] = array(
    'name' => t('Embed entities using embed:node:nid:viewmode'),
    'description' => t('Embed entities'),
    'dynamic' => TRUE,

  return $info;

I wrote a small module to allow embedding entities, such as nodes, via token:

 * Implements hook_tokens().
function mymodule_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
  $replacements = [];

  if ($type == 'embed') {

    // return $replacements;

    foreach ($tokens as $name => $original) {
      $args = explode(':', $name);

      if (count($args) > 1) {
        $entityType = $args[0];
        $entityId = $args[1];
        $viewMode = isset($args[2]) ? $args[2] : 'full';

        $entity = \Drupal::entityTypeManager()->getStorage($entityType)->load($entityId);
        $viewBuilder = \Drupal::entityTypeManager()->getViewBuilder($entityType);
        $renderable = $viewBuilder->view($entity, $viewMode);

        $replacements[$original] = \Drupal::service('renderer')->render($renderable);

      // @todo: use cache bubbleable_metadata better

  return $replacements;

The token [embed:node:1] actually works fine.

For some reason though, I get the error:

Fatal error: Cannot use object of type Drupal\Core\StringTranslation\TranslatableMarkup as array in /modules/token/src/Token.php on line 89

when saving any node, sometimes even regular admin pages/ forms. Uninstalling my module fixes the issue.

Is something wrong with how I return the replacements?


 * Extracts data from the token data for use in array_multisort().
 * @param array $token_info
 *   List of tokens or token types, each element must have a name key.
 * @return string[]
 *   List of the names keyed by the token key.
protected function prepareMultisort($token_info) {
  $by_name = [];
  foreach ($token_info as $key => $token_info_element) {
    $by_name[$key] = $token_info_element['name'];
  return $by_name;

1 Answer 1


See the example : https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Utility%21token.api.php/function/hook_token_info/8.3.x

Inside tokens there must be 3 levels, tokens][token_type][token].

Also tokens don't usually work like that and it will not be possible to validate that token, it is always a token type and that has tokens, which can have a type which then again has tokens. So you'd need to define types for your nested structure.

Not quite sure why you aren't using the entity_embed project to inject tokens, I assume this is supposed to be used inside a formatted text. https://www.drupal.org/project/entity_embed

  • the entity embed is not quite what i was looking for. i ended up writing an own filter though. using tokens for that really is the wrong use case. thanks!
    – Alex
    Jul 10, 2017 at 7:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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