To customise Breadcrumb there is two ways to achieve this:
Let's assume that you have a breadcrumb Home > Article Title and you want to customized it to be for instance Home > Tag > Article Title
- First option oriented object way.
First step Create class let's called it ArticleBreadcrumbBuilder should be located in YourModule/src/Breadcrumb folder.
<?php
namespace Drupal\YourModule\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Link;
use Drupal\taxonomy\Entity\Term;
class ArticleBreadcrumbBuilder implements BreadcrumbBuilderInterface {
public function applies(RouteMatchInterface $route_match) {
$parameters = $route_match->getParameters()->all();
if (isset($parameters['node'])) {
return $parameters['node']->getType() === 'article';
}
if (isset($parameters['term'])) {
return TRUE;
}
}
public function build(RouteMatchInterface $route_match) {
$breadcrumb = new Breadcrumb();
$node = \Drupal::request()->attributes->get('node');
$term_id = $node->field_tags->getValue()[0]['target_id'];
$term = Term::load($term_id);
$breadcrumb->addCacheContexts(["url"]);
$breadcrumb->addLink(Link::createFromRoute(t('Home'), '<front>'));
$breadcrumb->addLink(Link::createFromRoute(t('Articles'), '<none>'));
$breadcrumb->addLink(Link::createFromRoute(
$term->getName(), 'entity.taxonomy_term.canonical', ['taxonomy_term' => $term->id()]
));
$request = \Drupal::request();
$route_match = \Drupal::routeMatch();
$page_title = \Drupal::service('title_resolver')
->getTitle($request, $route_match->getRouteObject());
if (!empty($page_title)) {
$breadcrumb->addLink(Link::createFromRoute($page_title, '<none>'));
}
return $breadcrumb;
}
}
But we didn't finish yet, let's tell Drupal consider this class as Breadcrumb handler, so we should inject it as service:
Create YouModule.services.yml :
services:
YourModule.breadcrumb:
# The namespace + classname from your BreadcrumbBuilderInterface class
class: Drupal\YourModule\Breadcrumb\ArticleBreadcrumbBuilder
# Priority determines the order in which Breadcrumb services run.
tags:
- { name: breadcrumb_builder, priority: 100 }
- Second way is using hooks to achieve the same thing you can implement the hook_system_breadcrumb_alter in your YouModule.module
<?php
use Drupal\taxonomy\Entity\Term;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_system_breadcrumb_alter().
*/
function YourModule_system_breadcrumb_alter(Breadcrumb &$breadcrumb, RouteMatchInterface $route_match, array $context) {
// dpm($route_match);
$node = \Drupal::request()->attributes->get('node');
if ($node && $node instanceof Drupal\node\Entity\Node) {
if ($node->bundle() == 'article') {
// Add Articles item.
$breadcrumb->addLink(Link::createFromRoute(t('Articles'), '<none>'));
// Add category term item to breadcrumb.
// Change here the field_tags with your taxonomy you want to add to breadcrumb.
$term_id = $node->field_tags->getValue()[0]['target_id'];
$term = Term::load($term_id);
$breadcrumb->addLink(
Link::createFromRoute($term->getName(), 'entity.taxonomy_term.canonical', ['taxonomy_term' => $term->id()])
);
// Add title as breadcrumb item.
$request = \Drupal::request();
$route_match = \Drupal::routeMatch();
$page_title = \Drupal::service('title_resolver')
->getTitle($request, $route_match->getRouteObject());
if (!empty($page_title)) {
$breadcrumb->addLink(Link::createFromRoute($page_title, '<none>'));
}
}
}
}
And that's it, you can now alter your breadcrambs as you need!
Comments