The Node has attached a single Term.
Current breadcrumbs rendered
[HOME] >> [NODE_TITLE]
Want to render like this.
[HOME] >> [TERM] >> [NODE_TITLE]
Drupal Answers is a question and answer site for Drupal developers and administrators. It only takes a minute to sign up.
Sign up to join this communityYes @No Sssweat is right. I think you need to built a custom module for this.
Add Taxonomy Term to a Node's Breadcrumb in Drupal 8
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
A slightly more parametrized theme code example for non-node entities with taxonomy parents, made by combining Rishi Kulshreshtha's code with taxonomy parents addition by mfrosch
/**
* Implements hook_system_breadcrumb_alter().
*/
function THEMENAME_preprocess_breadcrumb(array &$vars) {
// proper taxonomy breadcrumbs for Commerce Products through field_category
$entity_type = 'commerce_product'; // TODO: change or verify
$taxonomy_field_name = 'field_category'; // TODO: change or verify
if (($entity = \Drupal::routeMatch()->getParameter($entity_type)) && $vars['breadcrumb']) {
$cache_tag = "{$entity_type}:{$entity->product_id->value}"; // TODO: change or verify
$breadcrumb = &$vars['breadcrumb'];
if (!empty($entity->$taxonomy_field_name->entity)) {
$node_url = array_pop($breadcrumb);
$term = $entity->$taxonomy_field_name->entity;
$storage = \Drupal::service('entity_type.manager')
->getStorage('taxonomy_term');
$parents = $storage->loadParents($term->id());
if (!empty($parents)) {
foreach ($parents as $index => $parent) {
array_push($breadcrumb, $parent->toLink());
}
}
array_push($breadcrumb, $term->toLink());
array_push($breadcrumb, $node_url);
// Implementing Cache.
$vars['#cache']['contexts'][] = "url.path";
$vars['#cache']['tags'][] = $cache_tag;
}
}
}
Taking a quick peek in contrib modules, as of this writting, there doesn't seem anything that you can use for D8.
Here is a creative quick and easy solution/suggestion:
With Views and bit of Rewrite Results/Template file + CSS you could create your own breadcrumbs view block.