0

I am trying to alter my title to include html. I have tried the following

function MODULENAME_views_pre_render(\Drupal\views\ViewExecutable $view) {
  if ($view->id() == 'products_test') {
    foreach($view->result as $value) {
      $value->_object->set('title', 'test - <b>My new Title</b>');
    }
  }
}

This outputs the title as test - <b>My new Title</b>, rather than rendering the text as HTML markup.

I tried passing the title to decode_entities(), but nothing changed.

I am using the Full content mode, rather than the Fields mode, if this makes any difference.

4 Answers 4

2

If you want to alter html, generally you'll be working with hook_preprocess_hook or a twig template override. This is the case for views as well. In the case of views, the template that renders the title is views-view.html.twig.

EDIT: Fastest way is just to use #markup

function my_module_preprocess_views_view(&$variables) {
  $variables['title'] = [
    '#markup' => 'test - <b>My new Title</b>'
  ];
}

So if you wanted to render the title with a b tag, you could do:

function my_module_preprocess_views_view(&$variables) {
  $existing_title = $variables['title'];
  $variables['title'] = [
    '#type' => 'inline_template',
    '#template' => '<b>{{ title }}</b>',
    '#context' => [
      'title' => $existing_title,
    ],
  ];
}

However, it's maybe not ideal to use tags for presentation and better to use classes and CSS styling. If you just want to add a CSS class to target, you could do a similar thing:

function my_module_preprocess_views_view(&$variables) {
  $existing_title = $variables['title'];
  $variables['title'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'views-title', // or whatever 
      ],
    ],
    '#value' => $existing_title
  ];
}

Both #container and #inline_template are render elements, and there are a lot available to you.

Of course, depending on what your theme and other modules are doing, the existing $variables['title'] might not just be a string, so you may need to adjust accordingly.

4
  • Hi, thanks for the details replied. But I am looking to but HTML elements in the Title not just wrap the title in a class.
    – May
    Commented Mar 22, 2022 at 7:19
  • Sorry, misread. Updated my answer to include how to use #markup
    – Mrweiner
    Commented Mar 22, 2022 at 20:25
  • Please feel free to revert my edit if you don't like it. But better recommend inline_template instead of html_tag which should rather be used for script tags for example.
    – leymannx
    Commented Mar 25, 2022 at 10:03
  • Actually I didn't know about inline_template -- that's great! Thanks for sharing.
    – Mrweiner
    Commented Mar 25, 2022 at 18:32
1

To change a view title, you can implement hook_preprocess_views_view(), which is what the Views UI module does, with views_ui_preprocess_views_view().

// Render title for the admin preview.
if (!empty($view->live_preview)) {
  $variables['title'] = [
    '#markup' => $view->getTitle(),
  ];
}

Using that code avoids the HTML markup used in the title is escaped/sanitized.

When the View UI module is installed, and you want to set the same view title in the the admin preview, the hook implemented by your module needs to be invoked after the one implemented by the View UI module. Keep in mind that views_ui_preprocess_views_view() uses also the following code.

if (!empty($view->live_preview) && \Drupal::moduleHandler()->moduleExists('contextual')) {
  $view->setShowAdminLinks(FALSE);
  foreach (['title', 'header', 'exposed', 'rows', 'pager', 'more', 'footer', 'empty', 'attachment_after', 'attachment_before'] as $section) {
    if (!empty($variables[$section])) {
      $variables[$section] = [
        '#theme' => 'views_ui_view_preview_section',
        '#view' => $view,
        '#section' => $section,
        '#content' => $variables[$section],
        '#theme_wrappers' => [
          'views_ui_container',
        ],
        '#attributes' => [
          'class' => [
            'contextual-region',
          ],
        ],
      ];
    }
  }
}

As side note, the default views-view.html.twig template used by the Views module used two template variables more: title_prefix and title_suffix.

  {{ title_prefix }}
  {{ title }}
  {{ title_suffix }}
0

Here is our solution to add markup to the view title:

function my_module_views_post_render(ViewExecutable $view, array &$output, CachePluginBase $cache) {
  $output['#post_render'][] = function ($content, array &$element) {
    $element['#title']['#markup'] = 'test - <em>My new Title</em>';
    return $content;
  };
}

Tested on Drupal 10.2.7.

-1

The other answers here are either clunky, don't cover all cases, or open security vulnerabilities. Instead, check out HTML Title module.

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.