1

I've created a custom controller that pulls content from another node (the body). That content is defined in the node as Raw HTML.

  public function page(Request $request): array {

    $nid = $request->attributes->get('_nid');
    $node_storage = $this->entityTypeManager()->getStorage('node');
    $node = $node_storage->load($nid);
    $content = $node->get('field_content')->value;

    // Load Entity using passed NID from key.
    $build = $content;
    // Return new Response($build);
    $render_array['snippet'] = [
      '#theme' => 'webpart_snippet',
      '#content' => $build,
      '#prefix' => '<div class="webpart_outer_wrapper">',
      '#suffix' => '</div>',
    ];
    return $render_array;

  }

I would like to render that content as if it were a native Symfony response. (e.g., correctly parse and HTML tags AND scripts)

In the node that I'm pulling in, I have, for example

<h1>This is text</h1> 

and that is exactly what is showing on the page

It should be

This is text

I have defined a custom theme as well as twig template

/**
 * Implements hook_theme().
 * Declare a new theme
 */
function custom_webpart_snippet_theme() {
  return [
    'webpart_snippet' => [
      'variables' => [
        'content' => '',
      ],
    ],
  ];
}
  • What is $render_array['snippet']? Shouldnt it just be $render_array['content'] and some renderable arrays? – Kevin Feb 10 at 23:25
  • 1
    Could you not skip the theme hook and twig, and simply do #type => markup, #markup => $build ? – stevekeiretsu Feb 10 at 23:35
1

Since this is a text area field, you need to specify a type of render element, processed_text.

$render_array['snippet'] = [
  '#theme' => 'webpart_snippet',
  '#type' => 'processed_text',
  '#text' => $node->field_content->value,
  '#format' => $node->field_content->format,
  '#prefix' => '<div class="webpart_outer_wrapper">',
  '#suffix' => '</div>',
];
  • @stevekeiretsu I tried that and it gets me very close. The problem that still remains with that is that the node contains javascript (yup, I know - bad idea, but I have to work with it for now). So... the remaining issue is that the javascript simply gets displayed (rather than being executed)... So - what now? – sea26.2 Feb 11 at 0:50
  • 1
    it contains <script></script> elements? I can't think offhand why, if an <h1> is now being interpreted as a heading and not quoted/escaped as markup, a script tag would behave any differently. I would expect it to work (yucky as it is). Not sure what else to suggest without setting up a whole environment to replicate your data etc, I'm afraid. Maybe drupal has some safety mechanisms I'm not aware. Actually, come to think of it, are you sure the script tags survive into $build and are not being filtered by field text format settings? No, wait, they must do if you see it displayed – stevekeiretsu Feb 11 at 1:17
  • @sea26.2 is your field's format set to full html? You could try hard coding it, '#format' => 'full_html', – No Sssweat Feb 11 at 1:36
  • @NoSssweat It is set to Raw HTML. – sea26.2 Feb 11 at 2:16
  • @stevekeiretsu You're right about Drupal Safety mechanism. According to api.drupal.org "#markup: (string) During rendering, this will be set to the HTML markup output. It can also be set on input, as a fallback if there is no theming for the element. This will be filtered for XSS problems during rendering; see also #plain_text and #allowed_tags." – sea26.2 Feb 11 at 2:16
0

The problem was in the template (twig) Simply the raw filter see doc description here

Non-working code

<div class="snippet-wrapper">
  <div>{{ content }}</div>
</div>

Working code

<div class="snippet-wrapper">
  <div>{{ content | raw }}</div>
</div>
  • 2
    Since it contains user entered text maybe escape it fist for security reasons. See drupal.stackexchange.com/a/290957/15055. {{ content | escape | raw }}. – leymannx Feb 11 at 6:26
  • 2
    Nice to know you found a solution. Although, I will say that it's not best practice to have scripts on your field. Ideally, you should include the script via a library. – No Sssweat Feb 11 at 6:33
  • @NoSssweat Thanks! And I agree. It is actually a really bad idea to put scripts inline within a field. It wasn't my idea and I didn't do it :) – sea26.2 Feb 11 at 16:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.