Stop using the #markup bad habit

When writing custom forms, you are often asked to add an extra paragraph of text between input fields. A solution that is used a lot is:

$form['explanation'] = [
  '#prefix' => '<p>',
  '#markup' => $this->t('Some text to explain the user what is going on here, using the #markup render element.'),
  '#suffix' => '</p>',

Although, this certainly does the job, my preference is to use an alternative solution:

$form['explanation'] = [
  '#type' => 'html_tag',
  '#tag' => 'p',
  '#value' => $this->t('A better way to add extra content is to use the html_tag render element.'),

The main reason is that #markup requires the string to be safe. When using html_tag, the chance to accidentally create a security hole is, therefore a bit lower. Besides, pre-processing can be targeted more easily, and the #attributes property is also available. Even nesting is possible with html_tag, so the places where #markup is used can be reduced dramatically.

When multiple values need to be shown and registering a custom theme implementation is overkill. Another option is to use the inline_template, which allows you to provide a (small) snippet of Twig as a template and output the (render) elements that are provided as the context:

$form['explanation'] = [
  '#type' => 'inline_template',
  '#template' => '<p>{{ explanation }}</p>',
  '#context' => [
    'explanation' => $this->('When a bit more complicated output is requested, the inline_template can be a welcome render element.'),

An advantage of the inline_template is that all Twig related functionality (e.g., filters) are available to generate the correct output.


Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.