I'm running Drupal 8.2.4.
I have a content type with a Link type field. I would like the link text to be the current user name by default and the URL to point to the current user account page. I put [current-user:display-name] as the text default value and [current-user:url:path] as the URL default value.
Without the Field Default Token installed the token substitution does not happen at all - the nodes are created with unprocessed tokens in the link text and URL. I install the Field Default Token and the strangest thing happens: as I save the default values, the tokens are evaluated and replaced at this very moment: MY user name and a link to MY account are saved as default values, so that when any user cretes a node, they get MY name and link in the Link field instead of theirs. Surely it's not supposed to work this way?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ndlarge created an issue. See original summary.

stefan.r’s picture

Title: Tokens for a Link field are not saved as Default values but instead the substituted text is saved » Tokens for a fields are not saved as Default values but instead the substituted text is saved

Yes, this is a bug, and this happens not only in link fields

milesw’s picture

Status: Active » Needs review
FileSize
648 bytes

I experienced a similar issue. After saving the field settings, token replacement for the field works correctly, but when you come back to the field settings you see a replaced value instead of the raw token.

The default value token is being saved correctly with the field config. But it is being replaced when you come back to the admin UI form, instead of showing the raw token version.

Here is a patch to this problem, at least for text fields. It should resolve the problem for other field types as well. Please test.

Smith76’s picture

Hi,
It works well for me with the patch.
Thanks

marassa’s picture

Works for me - thank you!

tstoeckler’s picture

FileSize
2.69 KB

Wow, very elegant fix for the field settings form. Works perfectly for me, as well. Added a quick test.

The problem described in the issue summary is a bit trickier to solve IMO, because default values no longer get re-applied at presave time in D8, like they were in D7. I think we will have to reimplement this behavior in hook_*_presave(), unfortunately...

tstoeckler’s picture

This works for me.

The rabbit hole goes a little bit further than I anticipated in #6, though. There was a protection brought over from D7 that prevented tokens being replaced before there is an ID because otherwise tokens like [node:id] but also [node:url], etc. lead to errors (exceptions in D8). In D7 that worked because default values were applied after the insert into the {node} table had happened - so there was already an ID - but before the insert into the field tables happened - so we had a chance to alter the value.

This is no longer possible in D8. I tried switching to hook_entity_insert() instead of _presave() but re-saving an entity from _insert() is not possible, unfortunately. So as far as I can tell we are left with using _presave(), which basically works, but blows up as soon as someone uses e.g. [node:id] as a token. :-/

Of course, if anyone has suggestions for a better solution, I'm all ears, this is really far from ideal.

stefan.r’s picture

Status: Needs review » Reviewed & tested by the community

Nice workaround, thanks!

piggito’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/field_default_token.module
@@ -17,6 +18,25 @@ use Drupal\Core\TypedData\OptionsProviderInterface;
+      if ($entity->get($field_name)->isEmpty()) {
+        $entity->get($field_name)->applyDefaultValue();

If a user wants to change field's default value to empty then this will change it back to default. I think this is a valid scenario so moving issue to Needs work.

Yuri’s picture

After applying the patch #7 and saving a field with token in default value, I get a fatal error. Log says:
TypeError: Argument 1 passed to field_default_token_entity_presave() must be an instance of EntityInterface, instance of Drupal\field\Entity\FieldConfig given in field_default_token_entity_presave() (line 23 of /data/disk/o1/static/opensocial8/html/sites/mysite.com/modules/field_default_token/field_default_token.module) #0 [internal function]: field_default_token_entity_presave(Object(Drupal\field\Entity\FieldConfig), 'field_config') #1 /data/disk/o1/static/opensocial8/html/core/lib/Drupal/Core/Extension/ModuleHandler.php(403): call_user_func_array('field_default_t...', Array) #2

pkej’s picture

I've tried both patch 6 and 7, both on their own, and both combined. The result is that the token disappears from the field when editing the content type.

Old content types won't substitute either, but neither does the token disappear from old content.

My mistake, I had a typo in the composer.json file. However, no substitution takes place with either patch.

danharper’s picture

Tried patch 7 and get Warning: call_user_func() expects parameter 1 to be a valid callback, function 'field_default_token_default_value_callback' not found or invalid function name in Drupal\Core\Field\FieldConfigBase->getDefaultValue() (line 398 of core/lib/Drupal/Core/Field/FieldConfigBase.php).

What's the way forward, happy to help with a patch?

Seems odd that this isn't in core now it's an extremely useful feature.

khyam’s picture

Patch #7 works perfectly for me.

@danharper - think the warning message will go after clearing cache

Yuri’s picture

[edited]
Now using D9.2.6
Patch #7 works for text fields. It does not work for entity reference fields, although the token replacement field is visible with the token selection link.

dqd’s picture

Status: Needs work » Reviewed & tested by the community

Just to confirm on latest Drupal 9.x core even with domain_access involded:

$ git apply -v 2841292- 7.patch
Checking patch field_default_token.module...
Checking patch tests/src/Functional/FieldDefaultTokenFieldEditFormTest.php...
Applied patch field_default_token.module cleanly.
Applied patch tests/src/Functional/FieldDefaultTokenFieldEditFormTest.php cleanly.

#9 I think turning back field to be empty as default should work after removing the token. I would recommend to put it back to RTBC.