Skip to content

Instantly share code, notes, and snippets.

@martin-klima
Created June 8, 2017 07:31
Show Gist options
  • Save martin-klima/bbb335dca0172b4836990e7914e51175 to your computer and use it in GitHub Desktop.
Save martin-klima/bbb335dca0172b4836990e7914e51175 to your computer and use it in GitHub Desktop.
Drupal 8: Custom breadcrumbs for node with hierarchical taxonomy term reference
services:
breadcrumb.breadcrumb:
class: Drupal\breadcrumb\BreadcrumbBuilder
tags:
- { name: breadcrumb_builder, priority: 10001 }
arguments: ['@router.request_context', '@access_manager', '@router.no_access_checks', '@path_processor_manager', '@config.factory', '@title_resolver', '@current_user', '@path.current']
<?php
namespace Drupal\breadcrumb;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\system\PathBasedBreadcrumbBuilder;
/**
* Build custom breadcrumb for Product node pages.
*
* Adds links to referenced taxonomy terms (product categories)
* include all nested terms in pattern:
*
* Home->Category view->Category1->Category1.2->Category1.2.3
*
* Strings usage:
* 'view.vyrobni_program.page_1' = route to view for breadcrumb level 2.
* 'Výrobní program' = title for breadcrumb level 2.
* 'field_product_category' = field name in node with reference to term.
* 'produkt' = Content type (node bundle) machine name for Products.
*
* Class BreadcrumbBuilder
*
* @package Drupal\breadcrumb
*/
class BreadcrumbBuilder extends PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface {
/**
* @var \Drupal\Core\Breadcrumb\Breadcrumb
*/
protected $breadcrumb;
/**
* Apply breadcrumb only on node type "product".
*
* {@inheritdoc}
*/
public function applies(RouteMatchInterface $route_match) {
$node = $route_match->getParameter('node');
if ($node) {
$node_type = $node->bundle();
if ($node_type == 'produkt') {
return TRUE;
}
}
return FALSE;
}
/**
* Builds the breadcrumb.
*
* {@inheritdoc}
*/
public function build(RouteMatchInterface $route_match) {
$this->breadcrumb = new Breadcrumb();
// Home - 1st level.
$this->breadcrumb->addLink(Link::createFromRoute('Home', '<front>'));
// Product view - 2nd level.
$this->breadcrumb->addLink(Link::createFromRoute('Výrobní program', 'view.vyrobni_program.page_1'));
// Get node and referenced term.
$node = $route_match->getParameter('node');
/** @var \Drupal\taxonomy\Entity\Term $categoryTerm */
$categoryTerm = $node->get('field_product_category')->entity;
// 3rd...n-th level: Add links to all parents.
$this->addTermChainLink($categoryTerm);
$this->breadcrumb->addCacheContexts(['route']);
return $this->breadcrumb;
}
/**
* Get parent taxonomy term.
*
* @param \Drupal\taxonomy\Entity\Term $term
* Taxonomy Term Entity.
*
* @return \Drupal\taxonomy\TermInterface|bool
* False if no parent.
*/
protected function getParentTerm($term) {
/** @var \Drupal\taxonomy\TermStorageInterface $termStorage */
$termStorage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
$termParents = $termStorage->loadParents($term->id());
if ($termParents) {
$termParent = reset($termParents);
return $termParent;
}
return FALSE;
}
/**
* @param \Drupal\taxonomy\Entity\Term $term
*/
protected function addTermChainLink($term) {
// Look for a parent of this term
/** @var \Drupal\taxonomy\Entity\Term $parentTerm */
if ($parentTerm = $this->getParentTerm($term)) {
// Recursive call this method for the parent.
$this->addTermChainLink($parentTerm);
};
/** @var Url $termUrl */
$this->addLinkToTerm($term);
}
/**
* @param \Drupal\taxonomy\Entity\Term $term
*/
protected function addLinkToTerm($term) {
/** @var Url $termUrl */
$termUrl = $term->toUrl();
$this->breadcrumb->addLink(Link::fromTextAndUrl($term->label(), $termUrl));
}
}
@shortthefomo
Copy link

miss spelling its product

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment