I'm programmatically creating a table in Drupal 8, using #type => 'table'. I'm adding some HTML to a table cell, however the output is being escaped so that the HTML is rendered as plain text, rather than as HTML.

From everything I read, it sounds like all output in twig templates are escaped by default.

I'm guessing I can override table.html.twig, but I'm guessing (hoping) there is a way to do it when defining the table, rather than overriding the template each time I want to create a new table that has HTML.

Does anyone know how to use HTML in a table cell in D8?

  • Try if this help Render plain text as HTML in Drupal 8 twig
    – Yogesh
    Commented Nov 21, 2016 at 6:40
  • Thanks - I've already seen how I can do it by overriding the twig template, what I'm looking for though is a way to do it when defining the form, so that I don't have to create a new template override each time I want to build a table that has HTML in it. Although I may just have to do that.
    – Jaypan
    Commented Nov 21, 2016 at 6:45

5 Answers 5


The answer (that worked for me) is to use FormattableMarkup:

use Drupal\Component\Render\FormattableMarkup;

$row[] = new FormattableMarkup('<span>@somevalue</span>', ['@somevalue' => 'some value']);

You can use inline_template while creating Table. inline_template description as per documentation page:

Provides a render element where the user supplies an in-line Twig template.

Here is example from Drupal 8 user permission page. The row cell type is defined as inline_template and HTML Markup and dynamic variables are passed to it:

  $form['permissions'][$perm]['description'] = array(
    '#type' => 'inline_template',
    '#template' => '<div class="permission"><span class="title">{{ title }}</span>{% if description or warning %}<div class="description">{% if warning %}<em class="permission-warning">{{ warning }}</em> {% endif %}{{ description }}</div>{% endif %}</div>',
    '#context' => array(
      'title' => $perm_item['title'],

Works for me using '#markup'.

$html= ['#markup' => '<div class="any_class">HTML</div>'];

$results = [
  '#type' => 'table',
  '#header' => [t('Column 1')],
  '#rows' => [

use Drupal\Component\Render\FormattableMarkup; is a great anwser however you can also do:

$row['myrow']['data'] = [
  '#markup' => '<h2>HELLO</h2>',

or for links you can just

 $row['myrow']['data']['#links'] = [
   $operations['edit'] = [
      'weight' => -5,
      'title' => $this->t('Edit Me'),
      'url' => Url::fromRoute('entity.someroute.edit', $route_parameters),

Do a search in your Site for all uses of "['data']["

also you can set some classes like

 $row['myrow']['data']['#attributes']['class'] = ['button', 'button-action', 'button--primary', 'button--small'];

This worked for me:

  // Build row
  $rows[ $one_nid ] = array(
    'title' => array(
      'data' => $one_node->getTitle(),
      'class' => 'donkey',
    'price_change_today' => array(
      'data' => array(
        '#markup' => $price_change.'<span class="price-change-icon"></span>'.$price_percent_change,
      'class' => 'burro',

// Return render array for table
return array(
  '#theme' => 'table',
  '#header' => $headers,
  '#rows' => $rows,

Thanks everyone for the code samples that helped me figure this out!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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