2

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
    Commented Feb 19, 2016 at 14:39
  • Yeah I was just working my way through all that.. it feels like it should be simpler.
    – cambraca
    Commented Feb 19, 2016 at 14:50
  • Have a look at drupal.stackexchange.com/a/180042/31.
    – Berdir
    Commented Feb 19, 2016 at 20:05

2 Answers 2

6

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
    Commented Dec 26, 2017 at 16:27
3

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
    Commented Feb 19, 2016 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
    Commented Jun 1, 2016 at 11:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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