Problem/Motivation

Today I worked with a member of my team to add a calculated entity reference base field to the user entity. We expected to see token pick that new field up and offer the tokens for it out of the box, given token's entity, fields, and entity reference support. We had done the same thing in Drupal 7 with success, so we expected at least as much from Drupal 8. Instead we hit up against an inconsistency in Token's entity support, and an inconsistency in token's field support.

(1.) The entity issue: If an entity type is already described to token by another module, token does not add tokens to it.

So in our case, because the User module defines some custom tokens for user entities, token would not expose our new base field and its referenced entity's tokens. We were forced to code this by hand, duplicating code that is already in the token module. It looks like this would be the case for many core entity types. Ughh.

(2.) The field issue: If an entity type defines a calculated base field, token does not provide a token for it.

So we realized that even if we fixed (1.) we were still out of luck because our field wasn't stored in the database. I can't imagine this restriction is by design.

Proposed resolution

Add a configurable setting to control token generation behavior

Similar to how Pathauto has entity type settings for which entity types the path field should be enabled, we propose adding a setting to control whether automatic tokens are generated for each entity type.

Setting behavior:

  • NULL (default): Maintains existing behavior - if an entity type already has custom tokens defined, no automatic tokens are generated
  • TRUE: Always generate automatic tokens for the entity type, regardless of existing custom tokens
  • FALSE: Never generate automatic tokens for the entity type

Implementation approach:

  • Extend \Drupal\token\TokenEntityMapper with methods to access the setting information
  • When no explicit setting exists, fall back to the current behavior
  • Once someone visits the settings page and saves it, store explicit TRUE/FALSE values for entity types
  • This also allows disabling token generation for entity types that will never be used for tokens

Field support improvements:

  • Expose calculated/computed base fields along with stored base fields
  • Support bundle base fields added via hook_entity_bundle_field_info_alter()

This approach provides backward compatibility while giving developers and site builders the flexibility to enable comprehensive token support when needed.

Remaining tasks

  • Implement configuration settings for entity type token generation
  • Extend TokenEntityMapper with setting access methods
  • Add support for computed and bundle base fields
  • Write tests for new functionality
  • Update documentation
  • Code review and testing

User interface changes

  • New configuration page/settings for controlling token generation per entity type

API changes

  • Expanded token generation to include computed and bundle base fields
  • New configuration schema for entity type token settings

Data model changes

  • New configuration storage for entity type token generation settings

Comments

chrisolof created an issue. See original summary.

chrisolof’s picture

Status: Active » Needs review
StatusFileSize
new1.96 KB

Initial stab at a patch.

Status: Needs review » Needs work

The last submitted patch, 2: token-consistent-entity-and-field-support-3047568-2.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

chrisolof’s picture

Status: Needs work » Needs review
StatusFileSize
new2.64 KB
new568 bytes
berdir’s picture

This is currently not done on purpose to avoid conflicts and duplicate between manually defined and generated tokens. E.g. node token names don't match 1:1 to field names and that will result in confusing duplicates and also even more tokens than there already are, which makes the UI overload problem worse until there is a better one.

chrisolof’s picture

@Berdir If I can't convince you to make this the default behavior... what if we made it an option/setting in the module (keeping today's limited tokens as the default)?

Also - what do you think about the idea of exposing all base fields (including computed)?

Attached patch is updated to include test coverage for computed base fields.

chrisolof’s picture

jonathanshaw’s picture

I see very strong arguments on both sides of this. Some possible ways of reconciling:

1) Hide the extra tokens this patch causes from the UI

2) Allow a setting to toggle the behavior, as suggested by @chrisolof

3) Create a new 'fields' group for each entity type, and put the full set of automatic tokens generated by this patch under that. So it's [node:fields:my_computed_base_field] and you have both [node:fields:title] and [node:title]. Because the extra fields are all collapsed up under 'fields' the clutter is minimised.

I think 3 is cleanest.

claudiu.cristea’s picture

I tried #6 but I cannot see my computed field token in the list.

EDIT: Probably because my computed field is a bundle field, added via hook_entity_bundle_field_info_alter()?

mautumn’s picture

My usecase was to have the UUID in the path using pathauto. I was slightly surprised that the token module didn't natively support this as this is core entity data. Anyway, I didn't like the idea of using a module specially for this - so I tried @chrisolof 's patch #6. It worked perfectly. Thanks very much indeed.

drcolossos’s picture

I have the same problem as #9 while using the same hook.

owenbush’s picture

StatusFileSize
new995 bytes
new3.28 KB

I too was struggling with bundle base fields and have updated the patch, it probably needs some tests but I am not sure the best way to approach those. Attached is a patch and interdiff for adding bundle base field support too.

berdir’s picture

Status: Needs review » Needs work

Here's a proposal: Add a setting to control this. Similar to how pathauto has an entity type setting for which entity types the path field should be enabled.

To keep the existing behavior, support NULL as an implicit default-behavior value.

We can extend \Drupal\token\TokenEntityMapper with a methods to make it easier to access that information.

If the stored value is an explicit TRUE or FALSE, respect that, if there is no value set, then fall back to the existing check. Once someone visits the settings page, and saves it, we store an explicit TRUE/FALSE for any entity type. That could also be useful if you know that some entity types will never be used for tokens, then you can disable that for you site.

Someone interested in working on that?

mpotter’s picture

Just FYI, I ran into a case with MetaTags where I needed to reference a Token for a computed field. Used the patch in #12 on my D9.0.10 site and seems to have worked. +1 for getting this in as an option somehow.

it-cru’s picture

I used patch from #12 with D9.3 to get [node:uuid] working for URL alias patterns. Hope we could get this patch into some of the next releases.

grevil’s picture

Furthermore, we should let the user decide, if the token module should even create a token for an entity, maybe via annotation.
I am currently working on a module, which needs tokens to display different legal text saved by entities. So additionally to my custom tokens defined in the module file, it automatically creates attribute tokens for my entity, which I want to permit. Doing this is currently quite dirty, since I need to use "hook_token_info_alter" to unset these tokens.

It works, but doing so, will still show the tokens in the Token Help Menu, even if they are not usable.

So perhaps we could add an Entity annotation for automatically creating tokens? What do you guys think? Or did I miss a fundamental way to do this properly?

jacobbell84’s picture

Looks like the latest release stopped the patch from applying, so I did a quick reroll

tim-diels’s picture

Used patch from #17 and works.
I use it for [taxonomy_term:uuid].

The issue probably should write out tasks so it is easier to see what is done and still needs to be done?

heddn’s picture

+1 to #13. But for now, i'm just going to use the latest patch.

mrweiner’s picture

Re-rolled #17 against latest dev.

unstatu’s picture

Hello @Berdir,

Does your proposal from #13 still valid? Does it worth to put effort on this?

In that case I could invest some time to try to push this issue.

mxr576’s picture

Opened #3466573: Expose UUID tokens for all content entities in Drupal core that adds UUID support for built-in content entities in Drupal core.

berdir’s picture

Re #21, yes, I still think that might be a viable way forward.

andriy khomych’s picture

+1 one for this patch.
I have a custom entity type, for which I was provided some custom tokens, but there is no way to have standard tokens work (like id, label, etc.).
This patch solves the issue.

mglaman’s picture

#20 still requires the field module to be installed, even though generic field support has been added:

  // Call proxy implementations.
  if (\Drupal::moduleHandler()->moduleExists('field')) {
    _field_token_info_alter($info);
  }

The module exists check can be removed.

ptmkenny’s picture

Status: Needs work » Postponed (maintainer needs more info)

#3466573: Expose UUID tokens for all content entities in Drupal core has been committed to 11.x.

I was using a patch in this issue to generate UUID tokens for custom entities, but I am now able to remove the patch and I still have UUID tokens as a result of the change referenced above.

Is there still a need for this issue? It seems like it has now been fixed upstream for most? use cases.

berdir’s picture

Status: Postponed (maintainer needs more info) » Active

My proposal from #13 is still valid and useful

mxr576’s picture

Issue summary: View changes

Updated the proposed solution based on Berdir's comment at #13, please double check.

a.dmitriiev’s picture

For those who were using patch #20 I have re-rolled the patch against version 1.17

a.dmitriiev’s picture

StatusFileSize
new2.75 KB

There was a typo in previous patch :( sorry

a.dmitriiev’s picture

StatusFileSize
new2.75 KB

That was really not a good idea to re-roll the patch in a rush, because there is another typo :(