Drupal - How can I add Taxonomy Term to a Node's Breadcrumb?
Themers who don't want to use a custom module to implement a BreadcrumbBuilder can change the breadcrumbs in a preprocess hook.
Example how you can add a link before the last link:
function mytheme_preprocess_breadcrumb(&$variables) {
$breadcrumb = &$variables['breadcrumb'];
$lastlink = array_pop($breadcrumb);
array_push($breadcrumb, [
'text' => 'New Link',
'url' => '/newlink',
]);
array_push($breadcrumb, $lastlink);
}
If you add a taxonomoy term from a node you would have to add both as cache tags and a cache context on the url to make this work.
We can implement custom breadcrumb either via module
or via HOOK_preprocess_breadcrumb
.
Via HOOK_preprocess_breadcrumb
:
Add this in your YOURTHEME.theme
/**
* Implements HOOK_preprocess_breadcrumb().
*/
function YOURTHEME_preprocess_breadcrumb(&$variables) {
if (($node = \Drupal::routeMatch()->getParameter('node')) && $variables['breadcrumb']) {
$breadcrumb = &$variables['breadcrumb'];
if (!empty($node->field_tags->entity)) {
$term_url = $node->field_tags->entity->toLink();
$node_url = array_pop($breadcrumb);
array_push($breadcrumb, $term_url);
array_push($breadcrumb, $node_url);
// Implementing Cache.
$variables['#cache']['contexts'][] = "url.path";
$variables['#cache']['tags'][] = "node:{$node->nid->value}";
}
}
}
Via module
:
In custom_breadcrumb.module
file
<?php
namespace Drupal\custom_breadcrumb;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\node\NodeInterface;
/**
* Class Breadcrumbs.
*
* @package Drupal\custom_breadcrumb
*/
class Breadcrumbs implements BreadcrumbBuilderInterface {
use StringTranslationTrait;
/**
* {@inheritDoc}
*/
public function applies(RouteMatchInterface $route_match) {
return $route_match->getRouteName() == 'entity.node.canonical' && $route_match->getParameter('node') instanceof NodeInterface;
}
/**
* {@inheritDoc}
*/
public function build(RouteMatchInterface $route_match) {
$node = $route_match->getParameter('node');
$breadcrumb = new Breadcrumb();
// By setting a "cache context" to the "url", each requested URL gets it's
// own cache. This way a single breadcrumb isn't cached for all pages on the
// site.
$breadcrumb->addCacheContexts(["url"]);
// By adding "cache tags" for this specific node, the cache is invalidated
// when the node is edited.
$breadcrumb->addCacheTags(["node:{$node->nid->value}"]);
// Add "Home" breadcrumb link.
$breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));
// Given we have a taxonomy term reference field named "field_tags" and that
// field has data, add that term as a breadcrumb link.
if (!empty($node->field_tags->entity)) {
$breadcrumb->addLink($node->field_tags->entity->toLink());
}
return $breadcrumb;
}
}
and then in custom_breadcrumb.services.yml
services:
custom_breadcrumb.breadcrumbs:
class: Drupal\custom_breadcrumb\Breadcrumbs
tags:
- { name: breadcrumb_builder, priority: 100 }
Both the ways are achievable, if your question is which one should be followed and which one should be referred as a best practice, refer https://drupal.stackexchange.com/a/238962/3808