The documentation for Token::replace() says:

   *   To ensure that the metadata associated with the token replacements gets
   *   attached to the same render array that contains the token-replaced text,
   *   callers of this method are encouraged to pass in a BubbleableMetadata
   *   object and apply it to the corresponding render array. For example:
   *   @code
   *     $bubbleable_metadata = new BubbleableMetadata();
   *     $build['#markup'] = $token_service->replace('Tokens: [node:nid] [current-user:uid]', ['node' => $node], [], $bubbleable_metadata);
   *     $bubbleable_metadata->applyTo($build);
   *   @endcode

The call to Token::replace() should do this and set the metadata on the returned build array.

Furthermore, if the result of the token replacement means that the rendered field item is uncacheable (because it depends on the user or the session), then a lazy builder should be used to prevent the whole page from being uncacheable.

Comments

joachim created an issue. See original summary.

joachim’s picture

Title: token replacement doesn't pass in BubbleableMetadata » token replacement doesn't pass in BubbleableMetadata; resulting cache data gets applied to entire page
Priority: Normal » Major
Issue summary: View changes
joachim’s picture

Here's a patch.

sophie.sk’s picture

Rerolled the patch against 2.0.0. Hope I got everything in it...

mangy.fox’s picture

Looks like the lazy builder isn't using the langcode passed in, so the rendered output is always in the default language.

mangy.fox’s picture

Finally got back around to this. Updated the patch to make sure the entity is in the correct language in the lazy loader.

mangy.fox’s picture

Added TrustedCallbackInterface for Drupal 9 compliance.

mangy.fox’s picture

mangy.fox’s picture

And another with latest changes.