Skip to content

It's not possible to update a title, just replace it #305

@andybroomfield

Description

@andybroomfield

Doing the following in a Page header event subscriber does now work as expected.

<?php

namespace Drupal\bhcc_mapping\EventSubscriber;

use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\localgov_core\Event\PageHeaderDisplayEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Set page title.
 *
 * @package Drupal\bhcc_mapping\EventSubscriber
 */
class PageHeaderSubscriber implements EventSubscriberInterface {

  use StringTranslationTrait;

  /**
   * Route match service.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * Constructs a bhcc_mapping PageHeaderSubcriber.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   Route match service.
   */
  public function __construct(RouteMatchInterface $route_match) {
    $this->routeMatch = $route_match;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [
      PageHeaderDisplayEvent::EVENT_NAME => ['setPageHeader', 0],
    ];
  }

  /**
   * Set page title and lede.
   */
  public function setPageHeader(PageHeaderDisplayEvent $event) {

    // Get the route name.
    $route_name = $this->routeMatch->getRouteName();

    // Only adjust the locations map route name.
    if ($route_name != 'bhcc_mapping.location_map') {
      return;
    }

    // Set cache max-age to 0 (no cache).
    $title = $event->getTitle();
    $title['#cache']['max-age'] = 0;
    $event->setTitle($title);
  }

}

This is because $event->getTitle(); is always NULL. Runing dpm($this->getTitle()) will return the correct page title via titleResolver as a string.

This has two issues:

  1. The page header block assumes that the title will always be replaced, so is checking the event first before setting the title. This should be set to the event so it can be modified by an event subscriber.
  2. Because it is a string, we can't add a cache max-age. This controller won't have a lede or subtitle so also can't be added there. Ideally we should be able to add cache-max-age to the block directly. There is a $event->setCacheTags($cacheTags) method that could be used, that only uses cache tags which won't help the scenario we have here.

Suggested fixes

  • For 1. Make sure we are sending the title to the event first (include lede and subtitle two) so they can be edited.
  • For 2. It's less clear. I can see the attraction of keeping it a string, so I'd suggest a way of setting cache max age and context in the event for this render array. Would that have consequences?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions