Drupal 8.3: Create Programmatic Custom Breadrumb

 

Well, today I'm making custom breadcrumbs.

If you or others have done things the right way, you can probably use Easy Breadcrumbs or Views Breadcrumb before doing it this way. But if you haven't, stick around and learn about Drupal core programmatic breadcrumbs.

There are multiple stack overflow posts on this but none of them actually seem to work for me. It seems that the code for Breadcrumbs in core has changed over time.

I have a single-language site, so bear that in mind.

First, you have to place the breadcrumb block so that it appears on the page in question. (Yes, in D8, breadcrumbs are in a block, like page title.)

Next, make a custom module. You need an mymodule_breadcrumb.info.yml file.

Then create mymodule_breadcrumb.services.yml:

services:
  mymodule_breadcrumb.breadcrumb_mybreadcrumbname:
    class: Drupal\mymodule_breadcrumb\Breadcrumb\myBreadcrumbNameBreadcrumbBuilder
    tags:
      - { name: breadcrumb_builder, priority: 100 }

Then create src/Breadcrumb/myBreadcrumbNameBreadcrumbBuilder.php:

namespace Drupal\mymodule_breadcrumb\Breadcrumb;
 
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
 
class myBreadcrumbNameBreadcrumbBuilder implements BreadcrumbBuilderInterface {
 
  /**
   * {@inheritdoc}
   */
  public function applies(RouteMatchInterface $attributes) {
    $parameters = $attributes->getParameters()->all();
    // This enables your "build" function to be utilized.
    return (isset($parameters['view_id']) && $parameters['view_id'] == 'my_view');
  }
 
  /**
   * {@inheritdoc}
   */
  public function build(RouteMatchInterface $route_match) {
    // Get the old-style arg array if you want it. Oh yeah.
    $route_array = array_values(array_filter(explode('/', $_SERVER['REQUEST_URI'])));
    $links = [];
    // Add a link to a view.
    $url = Url::fromRoute('view.content_listing.page_1', array('arg_0' => 'my_arg'));
    $links[] = Link::fromTextAndUrl(t('My view title'), $url);
    // Add a link to a specific node.
    $links[] = Link::createFromRoute(t(ucfirst($route_array[0])),'entity.node.canonical',
      ['node' => 360]);
    $links[] = Link::createFromRoute(t('Final Title, not linked'), '<none>');
    $breadcrumb = new Breadcrumb();
    // Cache breadcrumb by URL. 
    $breadcrumb->addCacheContexts(['url.path']);
    return $breadcrumb->setLinks($links);
  }
}

Some things you have which might be useful:

// Has all the args and the view id.
$route_match->getParameters()
// The route object:
$route_match->getRouteObject()

Some references:

Note: in a previous version of this post, I did not include a cache context. Updated to reflect caching contexts.

About the Author

Hi. My name is Jeremiah John. I'm a sf/f writer and activist.

I just completed a dystopian science fiction novel. I run a website which I created that connects farms with churches, mosques, and synagogues to buy fresh vegetables directly and distribute them on a sliding scale to those in need.

In 2003, I spent six months in prison for civil disobedience while working to close the School of the Americas, converting to Christianity, as one does, while I was in the clink.