Problem/Motivation

This will probably become a meta issue...

Proposed resolution

From the port issue:

I don't know the exact state of the 7.x port, that is possible yes, I never remember if I end up using rules field tokens or those from token.module ;) Test coverage definitely, references also possible now that I think about it, otherwise there would be some code for that somewhere. We did a bunch of specific references in custom code now, simply by setting the type of a field token to e.g. node, and 3 lines to pass the sub-tokens through. Should be relatively easy to make that generic, although we should probably do it as a sub-token then, similar to how entity field api/typed does that now, only downside is that it exposes 'entity' to the UI. It would look like this then:
- [node:some_file_field] => field view
- [node:some_file_field:target_id] => 5
- [node:some_file_field:entity:fid] => 5
- [node:some_file_field:description] => the file description.

i guess the way to do this would be to have token types for each field type, should be possible to get all that out of the property definitions.

As @davereid mentioned, there's also multi-value fields to consider, so possibly always include the delta.

Remaining tasks

User interface changes

API changes

Comments

Maouna’s picture

For my custom entities I need the field values as tokens
and I made a small module to do this automatically for a list of my entities.
My current version can be found here:
https://www.drupal.org/sandbox/maouna/2484739
I think it is connected to this issue, and maybe we can exchange our ideas.

Maouna’s picture

In field_tokens: What is the reason to only consider fields which are an instance of FieldConfigInterface? This excludes the basefields of the entities, which I would like to have available as tokens, too. I made a patch which changes that and so far everything seems fine. Can the authors give me some feedback on that, please?

Maouna’s picture

When a field is a timestamp or an entity reference, I would like to be able to chain it and made a patch for that. I do not like the idea of iterating over all fields of the entity (especially after this commit: http://cgit.drupalcode.org/token/commit/?id=a94c3ab), but I cannot think of a better way.

berdir’s picture

It's great that you're working on this. I would suggest that you open separate issues for new features, then we can discuss them separately.

Then we'll convert this issue into a meta.

Adding support base fields makes sense, as this should essentially give you free token integration for custom entity types. It wasn't done so far for historical reasons and because there are a lot of custom tokens already. We need to make sure that we're not creating too many duplicating tokens (for example in case core doesn't use the field names for the token names..). Also, if you do this, then you can just remove those checks completely and we can support all field definitions.

  1. +++ b/token.tokens.inc
    @@ -1274,6 +1274,38 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar
    +    // Chained token relationships.
    +    $fields = $entity->getFieldDefinitions();
    +    $token_service = \Drupal::token();
    +    foreach (array_keys($fields) as $field_name) {
    

    Looping over field definitions isn't a bad as looping over instantiated fields, so that's not as bad as it was before the referenced commit.

    However, that could still result in quit a few findWithPrefix() calls. Maybe we can optimize it to first find all unique "field:*" just once, and then loop over them and check if they are fields?

  2. +++ b/token.tokens.inc
    @@ -1274,6 +1274,38 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar
    +      $entity_type2 = FALSE;
    +      $entity2 = FALSE;
    +      if (isset($field_property_definition['value']) && ($field_property_definition['value']->getDataType() == 'timestamp' )) {
    +        $entity_type2 = 'date';
    +        $entity2 = $field->value;
    +      }
    +      elseif (isset($field_property_definition['entity'])) {
    +        $entity_type2 = $field_property_definition['entity']->getTargetDefinition()->getEntityTypeId();
    +        $entity2 = $field->entity;
    +      }
    

    Using $entity for something that's not an entity at all is pretty confusing. I think we should just move the findWithPrefix() call into thw two if's and then use variable names that make sense (or just hardcode it)

Maouna’s picture

Thank you very much for your feedback. I tried to do everything as you said and adapted the patches.
Here is the issue for the base field tokens: https://www.drupal.org/node/2493567
And here the issue for the chained field tokens: https://www.drupal.org/node/2493559

hussainweb’s picture

One of the tests required would be to test a field shared between two (or more) content types but with different labels. This setup will generate a different description for the token which should be tested. A bug related to this was fixed in #2497251: Description for reused fields not correct.

dasjo’s picture

Adding a reference to related efforts in the Rules module: #2632564: [META] Rules Twig-style Token support

We have switched to a Twig-style syntax and will provide access to any kind of Typed Data. Maybe a good point to exchange ideas or copy from each other :)

berdir’s picture

Title: Improve field support and add test coverage » [meta] Improve field support and add test coverage
Category: Task » Plan
Status: Active » Fixed

#2772673: Provide tokens for referenced entities in the active language. is now fixed as well.

#2497247: Field tokens in correct language is still open, but I think that is actually a duplicate of the previous issue, so marking this as fixed!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.