How to add contextual fields to breadcumb links? How can contextual fields be added to breadcrumb links?

For example, I have a hierarchical taxonomy vocabulary like this:

Animalia
--Chordata
----Vertebrata


On the Vertebrata page, the default breadcrumb looks like this:

Home &gt;&gt; Animalia &gt;&gt; Chordata


Each taxonomy term in the vocabulary has a "common name" field, so for Animalia it would be "animals", and for Chordata it would be "chordates". I would like the breadcrumb to look like this:

Home &gt;&gt; Animalia (animals) &gt;&gt; Chordata (chordates)


A similar example can be seen on this page, where a taxonomic rank field appears after each link in the classification breadcrumbs.

Besides achieving this with taxonomy breadcrumbs, I would be interested to know if a similar solution is achievable for menu breadcrumbs generated by the Menu Breadcrumb module.
I'm not aware of any contrib module that is capable of adding custom fields as suffix to breadcrumb links.

Fortunately, Drupal 8's modular architecture enables you to add your own breadcrumb builder service with a little bit of custom programming.

You will have to create an own module (within the following example, I'll call it my_module or MyModule respectively; you'll have to replace it accordingly) and add a my_module.services.yml file to its root directory.

Within this file you can define your own breadcrumb builder service. Make sure to let Drupal know, that it is a breadcrumb builder and in which order it should be processed by adding the relevant tags (read more about service tags here):

services:
  my_module.breadcrumb:
    class: Drupal\my_module\Service\MyModuleBreadcrumbBuilder
    arguments: ['@entity.manager']
    tags:
      - { name: breadcrumb_builder, priority: 10001 }


Now that Drupal knows about your breadcrumb builder and will process it fairly early because of the high priority given, you will have to create the according class.

Create a service class MyModuleBreadcrumbBuilder.php in your my_module/src/Service/ folder. Apart from the convention to letting its name end on BreadcrumbBuilder, you can actually name it to your liking. Just make sure to change the class name within the .services.yml file and the follwing example accordingly.

As you are up to creating a taxonomy breadcrumb builder, a good starting point is the TermBreadcrumbBuilder of the taxonomy core module, which we will extend in our example:

namespace Drupal\my_module\Service;

use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\taxonomy\TermBreadcrumbBuilder;

/**
 * My custom breadcrumb builder for Animalia.
 */
class MyModuleBreadcrumbBuilder extends TermBreadcrumbBuilder implements BreadcrumbBuilderInterface {

}


As your requirements seem to apply to a certain taxonomy vocabulary only, you should implement the BreadcrumbBuilderInterface::applies() method to check whether you are on a term page of that vocabulary.

This assures your breadcrumb builder won't run on other entities/vocabularies that don't feature your custom field (I used the ID my_vocabulary for your vocabulary; you will have to replace it accordingly):

use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\taxonomy\TermInterface;

[...]

/**
 * {@inheritdoc}
 */
public function applies(RouteMatchInterface $route_match) {
  return $route_match-&gt;getRouteName() == 'entity.taxonomy_term.canonical'
    &amp;&amp; ($term = $route_match-&gt;getParameter('taxonomy_term')) instanceof TermInterface
    &amp;&amp; $term-&gt;getVocabularyId() == 'my_vocabulary';
}


The next step is to implementing the BreadcrumbBuilderInterface::build() method, that returns the actual breadcrumb. Here, we'll add your custom field value to the shown parent term link labels.

As we extended the taxonomy breadcrumb builder before, we already have the entity manager and term storage available, which enable us to loading the localized versions of the terms.

Most of the proceedings match the TermBreadcrumbBuilder::build() method, so that I added a comment only where the term field value is added:

use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Link;

[...]

/**
 * {@inheritdoc}
 */
public function build(RouteMatchInterface $route_match) {
  $breadcrumb = new Breadcrumb();
  $breadcrumb-&gt;addLink(Link::createFromRoute($this-&gt;t('Home'), '&lt;front&gt;'));
  $term = $route_match-&gt;getParameter('taxonomy_term');
  $breadcrumb-&gt;addCacheableDependency($term);
  $parents = $this-&gt;termStorage-&gt;loadAllParents($term-&gt;id());
  array_shift($parents);

  foreach (array_reverse($parents) as $term) {
    $term = $this-&gt;entityManager-&gt;getTranslationFromContext($term);

    // The 'magic' happens here by loading the field value and
    // adding it to the link title; alter 'field_common_name' to
    // match your custom field ID.
    $my_field = $term-&gt;get('field_common_name');
    $term_name = $term-&gt;getName() . (!empty($my_field-&gt;getValue()[0]['value']) ? ' (' . $my_field-&gt;getValue()[0]['value'] . ')' : '');

    $breadcrumb-&gt;addCacheableDependency($term);
    $breadcrumb-&gt;addLink(Link::createFromRoute($term_name, 'entity.taxonomy_term.canonical', ['taxonomy_term' =&gt; $term-&gt;id()]));
  }

  $breadcrumb-&gt;addCacheContexts(['route']);
  return $breadcrumb;
}


After enabling the module (or flushing the caches, if you already enabled it before), you should now see your custom breadcrumbs when you open a term of your vocabulary.