In my template preprocess function I have a variable:

$test = "<p>this is a paragraph</p>";

and I pass it to my template:

$variables['test'] = $test;

and output it in twig:


but instead of getting a formatted paragraph, I'm getting the original output in plain text:

<p>this is a paragraph</p>

How do I get Drupal to render this as normal HTML?


Because twig auto-escapes unsafe content and your content isn't marked as safe.

You can explicitly tell it that it is with $test = Markup::create($test); but you should be very careful with that. If it contains any sort of user input, you might open yourself for XSS issues.

Better approaches are using a render array like ['#markup' => 'your text'] which by default will allow a certain amount of html tags but not all of them. You can also use an inline template as documented here: https://www.drupal.org/node/2311123.

Twig natively understands render arrays, so it doesn't matter for your template if you provide a render array or a string.

  • 2
    I found that by using the raw filter, I get the output I need, so: {{test|raw }} gives 'this is a paragraph' without the markup. – RominRonin Jan 22 '16 at 16:14
  • 1
    ok, so raw is unsafe and I don't understand how I should use the example documentation you provided – RominRonin Jan 22 '16 at 16:19
  • 1
    Ok, with the help of some #drupal IRC idlers I found this: drupal.org/node/2296163 which contains a few options for outputting markup in twig. – RominRonin Jan 22 '16 at 17:20
  • 1
    In my example, I retrieved $test from a db query, and the field data was stored with markup (basic html ckeditor field), so the #markup method was the most relevant for this use case. – RominRonin Jan 22 '16 at 17:21

These are two possibilities to wrap $test in a paragraph and pass it to the twig template:

$variables['test'] = [
  '#markup' => $test,
  '#prefix' => '<p>',
  '#suffix' => '</p>',

$variables['test'] = [
  '#type' => 'inline_template',
  '#template' => '<p>{{ text }}</p>',
  '#context' => [
    'text' => $test,

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.