Customize the list of entities for Token module

Created on 15 December 2023, about 1 year ago

Problem/Motivation

Currently, when we want to use a token in Barcode's value, only Node tokens are available. The node entity type is fixed in the block plugin form:

if ($this->moduleHandler->moduleExists('token')) {
      $form['value'] += [
        '#element_validate' => ['token_element_validate'],
        '#token_types' => ['node'], // Hardcoded.
      ];
      $form['token_help'] = [
        '#theme' => 'token_tree_link',
        '#token_types' => ['node'], // Hardcoded.
      ];
    }

It would be nice to make the entity list configurable, so #token_types also contains taxonomy terms, or any custom entities.

Steps to reproduce

1. Add a block via the Layout Builder
2. Show a list of possible tokens by clicking the link below "Value"
3. Only "Node" tokens are available here.

Proposed resolution

Show all types of entity tokens on the plugin form.

Workaround

Right now, this functionality can be achieved by installing the https://www.drupal.org/project/block_form_alter → module and adding a hook like this:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_block_plugin_form_alter(array &$form, FormStateInterface &$form_state, string $plugin) {
  if ($plugin == 'barcode') {
    $form['settings']['value']['#token_types'][] = 'myentity';
    $form['settings']['token_help']['#token_types'][] = 'myentity';
  }
}
✨ Feature request
Status

Active

Version

2.0

Component

Code

Created by

🇵🇱Poland gpietrzak Wrocław

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @gpietrzak
  • 🇺🇸United States tr Cascadia

    Sure, that's a reasonable feature. Please provide a patch and a test case!

  • 🇺🇸United States tr Cascadia
  • 🇺🇸United States tr Cascadia

    Your "workaround" doesn't actually work. There are two parts to supporting tokens for a new entity type. You took the first step, which is to add 'myentity' to the #token_types. But there's still the problem that you need to have an actual instance of 'myentity' and pass that to the token->replace() method. You're not doing that.

    I don't think that what you want to do will work in general. In order to use the node token, for example, the node object has to be in context. It is in context on a /node/{id} page - Drupal will automatically load the node that appears in the route and the Barcodes module can retrieve that node and resolve all the node tokens.

    But that only works if you place the Block on a /node/{id} page. If you place it on a /admin/configuration page or something like that, then there is no node in context - we don't have an instance of a node we can use for the tokens, so if you try to use a node token on a page like that they will not be resolved.

    The same is true of 'myentity'. How would Barcodes know how to find 'myentity' and know which instance of 'myentity' you want to use?

    And while I don't think this is really practical to do in a Block, it seems pretty easy to do with the Twig filter provided by the Barcodes module. In the Twig template for your content, you can use any variable available and pass it to the barcode filter. So if your template has an instance of 'myentity' in context, you can use that instance to render the data in your barcode.

    As far as I can tell, the Barcodes Block already gives you access to all the global tokens, but any others you might want to add need an instance of whatever object you're trying to use.

  • 🇺🇸United States tr Cascadia
  • Status changed to Closed: works as designed 16 days ago
  • 🇺🇸United States tr Cascadia
Production build 0.71.5 2024