1

For example, in a "blog post" page I'd like the breadcrumb to display like this:

Blog > Recipes > Recipe

I'm controlling all breadcrumbs from a single place, a class that implements BreadcrumbBuilderInterface. Its build method looks like this:

public function build(RouteMatchInterface $route_match) {
  $b = new Breadcrumb();

  $node = $route_match->getParameter('node');

  if ($node && $node->getType() == 'blog_post') {
    $b->addLink(Link::createFromRoute($this->t('Blog'), 'blog.home'));
    $b->addLink(Link::createFromRoute($this->t('Recipes'), 'blog.recipes_landing'));

    //I want this next item to not be a link, and to show "Recipe" and not the node title.
    //$b->addLink(Link::createFromRoute($this->t('Recipe'), 'nothing!'));
  }

  return $b;
}

How can I make this happen? I saw somewhere (not sure where, in a code comment perhaps) that this last item is supposed to be added in the theme layer, but I don't want to split my logic, especially since I don't just want all breadcrumbs to show the page title as the last item (instead, for example, I want it to say "Recipe" if the content type is blog_post).

3
  • That's quite a bit of work I think - you'll need a custom Breadbrumb class (the default works with typed links only), a custom BeadcrumbBuilder service (the default only works with the default Breadcrumb class), your own theme function (The links theme won't work for this, especially if you're interested in getting decent markup produced), a custom block for the new breadcrumb, etc. Hope I'm wrong but I don't see an easier way – Clive Feb 19 '16 at 14:39
  • Yeah I was just working my way through all that.. it feels like it should be simpler. – cambraca Feb 19 '16 at 14:50
  • Have a look at drupal.stackexchange.com/a/180042/31. – Berdir Feb 19 '16 at 20:05
4

You can do almost like in your suggestion. You just need to use '<none>' instead of 'nothing!'.

$b->addLink(Link::createFromRoute($this->t('Recipe'), '<none>'));
1
  • Well, that was disappointingly simple... I'll go remove a bunch of unnecessary code now. – cambraca Dec 26 '17 at 16:27
2

Here's the (very) complicated solution I implemented for this.

In a custom module, extend the Breadcrumb class, like this:

<?php

namespace Drupal\mymodule;

use Drupal\Core\Breadcrumb\Breadcrumb as Source;

class Breadcrumb extends Source {
  private $current = NULL;

  /**
   * @param string|NULL $title
   */
  public function setCurrentTitle($title) {
    $this->current = $title;
  }

  public function toRenderable() {
    $array = parent::toRenderable();
    $array['#current'] = $this->current;
    return $array;
  }

}

Then my build method from the question becomes this:

public function build(RouteMatchInterface $route_match) {
  $b = new Breadcrumb();

  $node = $route_match->getParameter('node');

  if ($node && $node->getType() == 'blog_post') {
    $b->addLink(Link::createFromRoute($this->t('Blog'), 'blog.home'));
    $b->addLink(Link::createFromRoute($this->t('Recipes'), 'blog.recipes_landing'));

    $b->setCurrentTitle($this->t('Recipe')); //yayhere!
  }

  return $b;
}

But, then, in my .theme file, I added this beautiful thing:

function mytheme_theme_registry_alter(&$theme_registry) {
  $theme_registry['breadcrumb']['variables']['current'] = [];
}

And, finally, the twig file became this:

{% if breadcrumb %}
  <nav class="breadcrumb container" role="navigation" aria-labelledby="system-breadcrumb">
    <h2 id="system-breadcrumb" class="visually-hidden">{{ 'Breadcrumb'|t }}</h2>
    <ol>
    {% for item in breadcrumb %}
      <li>
        {% if item.url %}
          <a href="{{ item.url }}">{{ item.text }}</a>
        {% else %}
          {{ item.text }}
        {% endif %}
      </li>
    {% endfor %}
    {% if current %}
      <li>{{ current }}</li>
    {% endif %}
    </ol>
  </nav>
{% endif %}

Nice, eh?

2
  • A side-effect I just noticed is that if there are no actual links and only a "current page", the thing won't show (because of the condition in the twig file). But I'm calling it "by design" since, on second thought, an empty label is pretty useless :) – cambraca Feb 19 '16 at 15:03
  • nice! how exactly do you implement the breadcrumb class? do i have to specify that in my services? and how do i make sure my custom builder class uses the custom breadcrumb class? – Alex Jun 1 '16 at 11:08

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.