3

In D8, I have a need to dynamically set the title of a views page display.

I've tried implementing both hook_views_pre_render and hook_views_post_build and setting the value of $view->build_info['title'], but Drupal seems to be ignoring it when setting the page title.

It seems like the code in Views where the title is set is in Drupal\views\Plugin\views\display\Page::execute()

The #title property on the render array in that method IS receiving my overwritten value from one of my hooks, but it's still ignore and is using the manually specified title on the display config.

What is going on!?

4
  • 1
    Do you have the metatag module enabled? It is still missing Views integration (drupal.org/node/2563647) so perhaps it overrides your title with the global default? Commented Feb 28, 2017 at 19:37
  • 1
    I do, but if that were the case, then specific views title I specify in the views config would not work either, but it does.
    – Brian
    Commented Feb 28, 2017 at 19:39
  • 1
    Is this view using a custom template file?
    – No Sssweat
    Commented Feb 28, 2017 at 23:34
  • 2
    What is going on!? The title is set in the route definition. See drupal.stackexchange.com/questions/224217/…
    – 4uk4
    Commented Mar 1, 2017 at 8:59

5 Answers 5

9

If someone else is looking for an answer, this is how I achieved this. I implemented hook_views_pre_render() where I called ViewExecutable::setTitle(). This allowed me to set the page title.

function MYMODULE_views_pre_render(ViewExecutable $view) {
  if ($view->id() == 'ABC') {
    $view->setTitle('MY CUSTOM TITLE');
  }
}
3
  • Just to appreciate you that this answer worked.
    – Pupil
    Commented Dec 27, 2017 at 12:48
  • This will only change the title on the page (i.e. h1) and not the title in the head of the document (i.e <head><title>Please work!</title></head>).
    – serverjohn
    Commented Aug 31, 2022 at 12:49
  • @serverjohn this somehow changed. Working for me in 9.4.7.
    – Edys Meza
    Commented Oct 14, 2022 at 21:32
4

If you want to change page title too you can use this snippet

\Drupal::routeMatch()->getRouteObject()->setDefault('_title', $title);

Hope this helps.

4
  • This no longer works. :-(
    – serverjohn
    Commented Aug 31, 2022 at 12:50
  • This works, but you also have to override the _title_callback to keep your changes, see below Commented Jul 20, 2023 at 14:06
  • $route->setDefault('_title_callback', NULL); Commented Jul 20, 2023 at 14:07
  • There is no need to edit an existing answer to repeat what another answer already said. If you want the other answer to be on top (which helps only with the default sorting), give to the other answer enough votes.
    – avpaderno
    Commented Jul 23, 2023 at 11:14
3

Setting only the _title property to set the page title tag was not enough in my case.

Overriding the title_callback property did the trick :-)

$title = 'something';
$route = \Drupal::routeMatch()->getCurrentRouteMatch()->getRouteObject();
$route->setDefault('_title_callback', function() use ($title) {
  return $title;
});
1
  • Did not work. D9.4.5
    – bigboy
    Commented Oct 5, 2022 at 21:46
1

Implemented using hook_views_post_render(). In this example the contextual filter is just added to the title.

/**
 * Implements hook_views_post_render().
 */
function THEME_views_post_render(&$view) {
    /** @var \Drupal\views\ViewExecutable $view */
    if ($view->id() === 'events' && isset($view->args[0])) {
        // Get year from contextual argument of the view.
        $year = $view->args[0];

        // Prefix year to title.
        $title = (string) t('@year Events', ['@year' => $year]);

        // Set view and page titles.
        $view->setTitle($title);
        \Drupal::routeMatch()->getRouteObject()->setDefault(
            '_title',
            $title
        );
    }
}
1

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.

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.