Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Add Taxonomy Term to a Node's Breadcrumb in Drupal 8
<?php
// src/Breadcrumbs.php
namespace Drupal\modulename;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Link;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\node\NodeInterface;
/**
* Class Breadcrumbs.
*
* @package Drupal\modulename
*/
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_section", and that field has data,
// Add that term as a breadcrumb link.
if (!empty($node->field_section->entity)) {
$breadcrumb->addLink($node->field_section->entity->toLink());
}
return $breadcrumb;
}
}
# modulename.services.yml
services:
modulename.breadcrumbs:
class: Drupal\modulename\Breadcrumbs
tags:
- { name: breadcrumb_builder, priority: 100 }
@jonpugh

This comment has been minimized.

Copy link
Owner Author

commented May 5, 2016

I needed to take a taxonomy term from a node and add it to the breadcrumbs.

After a painful crash course in Drupal 8 Services and BreadcrumbBuilder, along with an unexpected ride through learning cache contexts and tags, I finally got this to work properly... I think.

The trickiest parts were the caches stuff, so I made sure to add some comments to explain what I think is happening.

@olmas-git

This comment has been minimized.

Copy link

commented May 27, 2016

Hi, I am a new of drupal, how can I implement your code?

@RishiKulshreshtha

This comment has been minimized.

Copy link

commented Jun 19, 2017

@olmas-git, @jonpugh has already provided the whole module in this gist. In case if you need a ready made bundle you can use my module which is built using the same code or I would suggest you to go with 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}";
    }
  }
}

For more information, follow https://drupal.stackexchange.com/a/239154/3808

@mfrosch

This comment has been minimized.

Copy link

commented Jun 19, 2017

If you also want the parents you can replace

    if (!empty($node->field_section->entity)) {
      $breadcrumb->addLink($node->field_section->entity->toLink());
    }

with

    if (!empty($node->field_section->entity)) {
      $term = $node->field_section->entity;
      $storage = \Drupal::service('entity_type.manager')
        ->getStorage('taxonomy_term');
      $parents = $storage->loadParents($term->id());

      if (!empty($parents)) {
        foreach ($parents as $index => $parent) {
          $breadcrumb->addLink($parent->toLink());
        }
      }

      $breadcrumb->addLink($term->toLink());
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.