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
Not sure if typo but my
Not sure if typo but my_events.service.yml should be my_events.services.yml
Joshi... it was a typo on my
Joshi... it was a typo on my end, when entering the support request.
I checked and the filename is services.yml.
Few questions
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
Hi Marcelovani,
Hi Marcelovani,
Thank you for the input.
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
Thanks for this last comment!
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 !