20

I have some html content, it comes from a external library so i can not change it, it has many <span> and <div> tags with attributes like: <span style="color: #0000ff;">, but when i use:

$render = array(
  '#markup' => $myhtmlcontent,
);

In a render array, Drupal strips the attributes, and it keeps just <span> without the styles.

So, how can I avoid Drupal changes what I pass as markup, which doesn't need any filter because the library makes it safe, or at last make it allow styles?

  • style attributes are always stripped out – Yzmir Ramirez Oct 25 '16 at 21:26
26

Use inline template:

  return [
    '#type' => 'inline_template',
    '#template' => '{{ somecontent }}',
    '#context' => [
      'somecontent' => $somecontent
    ]
  ];

In your case without context, just straight up html.

You can also use the html_tag element for things like script or link and so on.

  • 2
    This filters out IFRAME tags. – joachim May 2 '16 at 14:40
  • 1
    And script and style tags – Yzmir Ramirez Oct 25 '16 at 21:25
  • 8
    Try {{ variable | raw }} or <tag>{{variable}}</tag> – user21641 Oct 26 '16 at 11:48
  • 1
    @IvanJaros That will just skip auto escaping the variable , but the ` \Drupal\Component\Utility\Xss::filterAdmin()` will still filter out tags like <script> and style attributes. The only way I have seen so far is to add a Javascript file as a library and add '#attached' => 'library' => "module_name/library_key_in_yml" to the above return. @see drupal.stackexchange.com/questions/211078/… – Yzmir Ramirez Oct 29 '16 at 23:04
  • 1
    Anyone know if this the only/best way of doing HTML comments? e.g. <!-- Hello, World! --> (nb: as mentioned above you need '| raw') – William Turrell Aug 2 '18 at 11:58
15

As documented in Render API overview, in Drupal 8 the string passed to #markup is passed through \Drupal\Component\Utility\Xss::filterAdmin(), which strips known XSS vectors while allowing a permissive list of HTML tags that are not XSS vectors. You can use #allowed_tags to set the list of allowed tags, but that would not strop Drupal from stripping attributes (e.g. style).

$output['filtered_string'] = array(
  '#markup' => '<em>This is filtered</em>',
  '#allowed_tags' => ['strong'],
);

Since in your case you are passing complex HTML markup, you should use #type (as suggested from Ivan Jaros or use #theme. In this case, #type seems a better solution.

You could also implement a new type, with a render element plugin, but if that is the only case where you need it, then implementing a render element plugin is probably excessive.

10

In a render array, simply do this:

return [
  '#children' => $html,
];

E.g. if the $html was produced with PHP's highlight_string(), it will contain style attributes which would be removed with #markup. But #children preserves them.

9

If you want to add plain Markup to render arrays, you can create it using \Drupal\Core\Render\Markup. This will allow you to put raw HTML into something. For instance, here's how it's used in the Permission Report module to put HTML into tables:

$rows[] = [
  [
    'data' => $this->l($meta['title'], new Url('permission_report.permission', ['user_permission' => $perm], $options)),
  ],
  ['data' => $users_having_role],
  ['data' => Markup::create(implode(', ', $display_roles))],
];
  • 3
    I know this is two years down the line but thanks. For beginners let me simplify it: use \Drupal\Core\Render\Markup $HeaderSettingsIcon = Markup::create('<i class="fa fa-cogs"></i>'); – Ngatia Frankline Aug 19 '17 at 21:01
  • @NgatiaFrankline, is there a way to offer you my gratitude? – dresh Dec 10 '18 at 18:43
  • I did this : $form['first_name'] = array( '#type' => 'textfield', '#title' => t('Your First Name :'), '#required' => TRUE, '#attributes' => array( 'class' => array('form-control req'), 'name'=>array('first_name')), '#label_attributes' => array('class' => array('mandatory')), '#children' => Markup::create('<span class="error-text">Please enter the valid First Name</span>'), ); – dresh Dec 10 '18 at 18:45

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.