Hey all,

I am working on a custom module that displays events. The events come from a remote service and I to set the breadcrumbs for the Events (list) page and the individual event page.

The individual event page works as intended (siteName/Events/EventName), however the event (list) page does not work (siteName/Events). Using devel_dump and echo, I am able to see what is executing, the _Construct executes, but the applies() method does not fire in my EventsBreadcrumbsBuilder class.

I think it has something to do with my route.

I'm including all file info.

Here are the two routes:

my_events.routing.yml

#List page for this site's events
my_events.events:
  path: '/events/{view}/{date}/{cat}'
  defaults:
    _title: 'Events'
    _controller: '\Drupal\my_events\Controller\RemoteEventsController::eventsListView'
    view: 'week'
    date: 'now'
    cat: '0'
  requirements:
    _access: 'TRUE'
  options:
    no_cache: 'TRUE'

#Single event page
my_events.event:
  path: '/event/{id}'
  defaults:
    _title: 'Event'
    _controller: '\Drupal\my_events\Controller\SingleRemoteEventController::content'
  requirements:
    _access: 'TRUE'
    id: \d+
  options:
    no_cache: 'TRUE'

my_events.service.yml file

services:
  my_events.breadcrumb:
    class: Drupal\my_events\Breadcrumb\EventsBreadcrumbBuilder
    arguments: ['@config.factory']
    tags:
      - { name: breadcrumb_builder, priority: 100 }

EventsBreadcrumbBuilder.php (src/Breadcrumbs/EventsBreadcrumbsBuilder)

<?php

namespace Drupal\my_events\Breadcrumb;

use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Link;
use Drupal\my_events\Utility\EventFunctions;

/**
 * Provides a event(s) breadcrumb builder.
 */
class EventsBreadcrumbBuilder implements BreadcrumbBuilderInterface {

  /**
   * The configuration object factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The route_name object.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeName;

  /**
   * Constructs a EventBreadcrumbBuilder object.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The configuration object factory.
   */
  public function __construct(ConfigFactoryInterface $config_factory = NULL) {
    $this->configFactory = $config_factory ?: \Drupal::configFactory();
  }

  /**
   * {@inheritdoc}
   */
  public function applies(RouteMatchInterface $route_match) {
    $route_name = trim($route_match->getRouteName());

    // All routes must begin or contain 'my_events'.
    if (str_contains($route_name, 'my_events') === FALSE) {
      return FALSE;
    } else {
      return TRUE;
    }

  }

  /**
   * {@inheritdoc}
   */
  public function build(RouteMatchInterface $route_match) {

    // Get the site config, so we can access the site name.
    $site_name = $this->configFactory->get('system.site')->get('name');
    $func = new EventFunctions();
    $breadcrumb = new Breadcrumb();

    // Add a link to the homepage as our first crumb.
    $breadcrumb->addLink(Link::createFromRoute($site_name, '<front>'));
    $breadcrumb->addLink(Link::createFromRoute('Events', 'my_events.events'));
    $route_name = $route_match->getRouteName();

    if ($route_name == 'my_events.event') {
      /* Get Event information from external source
       * Returns an array with breadcrumb items ['id', 'event_title']
      */
      $bc_items = $func->getBreadcrumbItems($route_name);
      $id = $bc_items[1];
      $breadcrumb->addLink(Link::createFromRoute($bc_items['label'], 'my_events.event', ['id' => $id]));
    }
    // Don't forget to add cache control by a route.
    // Otherwise all pages will have the same breadcrumb.
    $breadcrumb->addCacheContexts(['route']);

    // Return object of type breadcrumb.
    return $breadcrumb;
  }

}

Any ideas are welcome.

Michael

Comments

joshi.rohit100’s picture

Not sure if typo but my_events.service.yml should be my_events.services.yml

macaddicus’s picture

Joshi... it was a typo on my end, when entering the support request.

I checked and the filename is services.yml.

marcelovani’s picture

I see you are using PHP 8 functions, can you confirm that you are running this on PHP 8?

In build() you have a condition `if ($route_name == 'my_events.event') `. Would you need also a condition to cover route `my_events.events`?

Just to debug, in applies(), can you hard code `return TRUE`?

An obvious question, do you have the breadcrumb block placed on the relevant page?

Out of interest, why do you need this `?: \Drupal::configFactory();`

Technical Architect | Lead Software Engineer

macaddicus’s picture

Hi Marcelovani,

Thank you for the input.

In build() you have a condition `if ($route_name == 'my_events.event') `. Would you need also a condition to cover route `my_events.events`?

Originally, I didn't use a condition in the build() for my_events.events. I was allowing the breadcrumb links directly above the condition to be used for the 'my_events.events' route. However, we have added breadcrumb login specifically for the events page, which made me add a condition for 'my_events.events'.

Thank you for asking about the use of `?: \Drupal::configFactory();`... it was not needed.

The real issue was the 'priority' setting in 'my_events.services.yml'. Almost all of the information I could find showed 'priority: 100' and this did not work with 'my_events.events' route. I noticed in the webform module, the setting for the breadcrumb service is 'priority: 1002'. I tried this and still nothing. Then I changed the priority to 9999 and my breadcrumbs began to work on the events page... and they still work on the event page.

I tried to look for documentation on Drupal priority settings and could not find much. I also tried to find a way to use devel_dump() all of the priorities via \Drupal->service... not luck there either. Any advice with priorities?

Thank you,

Michael

flyke’s picture

Thanks for this last comment!

I had the same issue, a custom module with a custom admin route, the breadcrumbs were not working.

Not with priority 100, not with priority 1002.

Priority 9999 did the trick to get the custom breadcrumbs working !