3

I'm using Drupal 8.3.0-beta1 and I need to write a custom module to customize breadcrumbs in some cases. On of this cases consists in customizing the breadcrumb in path taxonomy/term/% but with my current code there is a problem:

When I visit taxonomy/term/% the "applies" callback of my custom implementation of BreadcrumbBuilderInterface doesn't get executed. However, it gets called on taxonomy/term/%/edit. Maybe that's the reason why the core breadcrumb builder only returns "Home /" in this case. Do you think this is a core bug or I have done something wrong?

Notice I have another implementation of BreadcrumbBuilderInterface for nodes which works well. This is my code:

custom_breadcrumb.info.yml

name: 'Custom breadcrumbs'
description: 'Custom breadcrumbs implementation'
package: 'Custom'
# core: 8.x
type: module

version: '8.x-1.0'
core: '8.x'
project: 'custom_breadcrumb'
datestamp: 1443649740

custom_breadcrumb.services.yml

services:
  custom_breadcrumb.breadcrumb_blog:
    class: Drupal\custom_breadcrumb\Breadcrumb\BlogBreadcrumbBuilder
    tags:
      - { name: breadcrumb_builder, priority: 101 }

src/Breadcrumb/BlogBreadcrumbBuilder.php

<?php

namespace Drupal\custom_breadcrumb\Breadcrumb;

use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\LinkGeneratorTrait;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Link;
use Drupal\taxonomy\Entity\Term;

class BlogBreadcrumbBuilder implements BreadcrumbBuilderInterface {
  use LinkGeneratorTrait;
  use StringTranslationTrait;

  /**
   * @inheritdoc
   */
  public function applies(RouteMatchInterface $route_match) {    
    // This breadcrumb apply only for blog taxonomy terms of vocabulary 'categoria_blog'.    
    $parameters = $route_match->getParameters()->all();

    /*
     * CORE BUG? applies callback gets called on "taxonomy/term/%/edit" but not in "taxonomy/term/%"
     * https://www.drupal.org/node/2622840
     */
    if (isset($parameters['taxonomy_term'])) {
      $term = $parameters['taxonomy_term'];

      if ($term->getVocabularyId() == 'categoria_blog') {
        return TRUE;
      }
    }

    return FALSE;
  }

  /**
   * @inheritdoc
   */
  public function build(RouteMatchInterface $route_match) {

    $parameters = $route_match->getParameters()->all();

    if (isset($parameters['taxonomy_term'])) {

      $term = $parameters['taxonomy_term'];

      // Breadcrumbs set up (cache settings are so important!).
      $breadcrumb = new \Drupal\Core\Breadcrumb\Breadcrumb();
      $breadcrumb->addCacheContexts(["url"]);
      $breadcrumb->addCacheTags(["taxonomy_term:{$term->id()}"]);

      $breadcrumb->addLink(Link::createFromRoute($term->getName(), '<none>'));
    }

    // Reverse order for this to work!!!.
    $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));
    return $breadcrumb;
  }
}
  • Is taxonomy/term/% overridden as a view? – mradcliffe Mar 8 '17 at 15:47
  • Yes, I have the standard "Taxonomy term" view enabled but if I disable it and then rebuild the cache the result is the same. I also have panels enabled, but I'm not overriding the taxonomy term path. – Roger Mar 8 '17 at 18:36
  • I just tried to update to core 8.3.0-rc1 and problem persists. I also tried with a clean installation of 8.3.0-rc1 and the result is the same – Roger Mar 10 '17 at 8:24
5

The taxonomy module provides a default breadcrumb service and if you have a look at the declaration of this in the taxonomy.services.yml file you will see it has a priority of 1002.

Setting the priority of your breadcrumb service to a value higher than this should get Drupal to use your breadcrumb rather than the default one.

Something like this should do the trick:

custom_breadcrumb.services.yml

services:
  custom_breadcrumb.breadcrumb_blog:
    class: Drupal\custom_breadcrumb\Breadcrumb\BlogBreadcrumbBuilder
    tags:
      - { name: breadcrumb_builder, priority: 10001 }
1

according to https://www.drupal.org/docs/8/api/services-and-dependency-injection/service-tags

A higher priority will be used over a lower priority.

and since the default implementation of TermBreadcrumbBuilder has a priority of 1002 the priority needs to be set to at least 1003.

services:
custom_breadcrumb.breadcrumb_blog:
class: Drupal\custom_breadcrumb\Breadcrumb\BlogBreadcrumbBuilder
tags:
  - { name: breadcrumb_builder, priority: 10003 }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.