Score:0

How to render content entity as a token replacement?

us flag

I wonder what's the right way to render entity render array as a token replacement (value). I found 3 different ways in the contrib:

Looking at https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Renderer.php/function/Renderer%3A%3ArenderPlain/9.3.x, it looks like this method should be the correct one, given the description:

Useful for instance when rendering the values of tokens or emails, which need a render array being turned into a string

Is that true?

4uk4 avatar
cn flag
Yes, if you need to turn a render array into a string without bubbling up cache metadata to the page (where it doesn't belong because the content goes into an email), then this is true.
us flag
Thanks. This is interesting, because I interpreted this as useful for rendering the values of token generally ("or").
Score:1
cn flag

No, for example the mentioned AET module is mainly targeted to render entities via the token filter in the body field of other entities. Then the render method is more appropriate to bubble up the metadata and also not to replace placeholders too early. But this not perfect, either.

You find a better example in the core media embed filter, where in a token you would merge with $bubbleable_metadata:

\Drupal\media\Plugin\Filter\MediaEmbed::renderIntoDomNode()

  /**
   * Renders the given render array into the given DOM node.
   *
   * @param array $build
   *   The render array to render in isolation.
   * @param \DOMNode $node
   *   The DOM node to render into.
   * @param \Drupal\filter\FilterProcessResult $result
   *   The accumulated result of filter processing, updated with the metadata
   *   bubbled during rendering.
   */
  protected function renderIntoDomNode(array $build, \DOMNode $node, FilterProcessResult &$result) {
    // We need to render the embedded entity:
    // - without replacing placeholders, so that the placeholders are
    //   only replaced at the last possible moment. Hence we cannot use
    //   either renderPlain() or renderRoot(), so we must use render().
    // - without bubbling beyond this filter, because filters must
    //   ensure that the bubbleable metadata for the changes they make
    //   when filtering text makes it onto the FilterProcessResult
    //   object that they return ($result). To prevent that bubbling, we
    //   must wrap the call to render() in a render context.
    $markup = $this->renderer->executeInRenderContext(new RenderContext(), function () use (&$build) {
      return $this->renderer->render($build);
    });
    $result = $result->merge(BubbleableMetadata::createFromRenderArray($build));
    static::replaceNodeContent($node, $markup);
  }
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.