0

Im breaking my head around getting the breadcrumbs set properly on views page.

my views' page address is "teachers/%" where % is a term-id.

I have a content type called 'program' with a field taxonomy term reference field "field_department"

I want to set my breadcrumb for the page 'teachers/%' to be the breadcrumbs of the program associated with % + the program itself.

my site is using also menu_breadcrumb which gives the rule for my program breadcrumbs.

I want the the breadcrumb of 'teachers/7' will behave as if it is the menu child of node/22.

I tried both hook altering the breadcrumbs or adding the pages to the menu dynamically but I dont manage.

Can this be done? and how?

2 Answers 2

1

Views breadcrumbs can be tricky. You can create a module and a class that implements BreadcrumbBuilderInterface and do:

class MyBreadcrumbBuilder implements BreadcrumbBuilderInterface {

  use StringTranslationTrait;

  /**
   * The AdminContext service.
   *
   * @var \Drupal\Core\Routing\AdminContext
   */
  protected $adminContext;

  /**
   * The AliasManager service.
   *
   * @var \Drupal\Core\Path\AliasManagerInterface
   */
  protected $aliasManager;

  /**
   * The EntityTypeManager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(
    AdminContext $admin_context,
    AliasManagerInterface $alias_manager,
    EntityTypeManagerInterface $entity_type_manager
  ) {
    $this->adminContext = $admin_context;
    $this->aliasManager = $alias_manager;
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function applies(RouteMatchInterface $route_match) : bool {
    if ($this->adminContext->isAdminRoute()) {
      return FALSE;
    }

    // Using route_match, check if the current route is a view and which view id
    // and return true or false
  }

  /**
   * {@inheritdoc}
   */
  public function build(RouteMatchInterface $route_match) : Breadcrumb {
    $breadcrumb = new Breadcrumb();

    // create your breadcrumbs...

    return $breadcrumb;
  }

}
3
  • Thank you for helping! It is the part of " // create your breadcrumbs..." that i am not sure how to do. I have the nid of the node I want to inherit from but how do I get its breadcrumbs? i wish there were something like Breadcrumb::load($node);
    – crab
    Commented Feb 19, 2020 at 19:32
  • You are building your own chain here - so you would have to leverage other means. Like using entityTypeManager to load a node and get its information. If your first argument is a term ID, I am not sure how you would derive any sort of node id out of that (in this case, 22?) to load and attach information from?
    – Kevin
    Commented Feb 19, 2020 at 19:49
  • I use entity query. i got that part of the code already. as for building my trail of breadcrumbs. how can i know what breadcrumb trail my node has? it is ruled by its location in the menu, i could perhaps load the menu and build the breadcrumbs from there, but im hoping for a shortcut.
    – crab
    Commented Feb 19, 2020 at 20:09
0

Ok finally i did this way:

 public function build(RouteMatchInterface $route_match) : Breadcrumb {
    $breadcrumb = new Breadcrumb();
    $this->menu_link_manager = \Drupal::service('plugin.manager.menu.link');
    $node_id = 22; //I use a query to get the entities according to the routeMatch argument
    $results = $this->menu_link_manager->loadLinksByRoute('entity.node.canonical', array('node' => $node_id));
    foreach ($results as $result){
      if ($result->getMenuName() == "main"){
        $links = $this->_build_links($result,[Link::createFromRoute(t('Home'), '<front>')]);
        //here i use just a string 'Home', ideally this string should be taken from breadcrumbs\site settings.
      }
    }
    $breadcrumb->setLinks($links);
    return $breadcrumb;
  }
  private function _build_links($menu_item, $links){
    if ($menu_item->getParent() && $parent = $this->menu_link_manager->createInstance($menu_item->getParent())) {
     $links = $this->_build_links($parent, $links);
    }
    $title = $menu_item->getTitle();
    $routeName = $menu_item->getRouteName();
    $routeParameters = $menu_item->getRouteParameters();
    $options = $menu_item->getOptions();
    $links[] = Link::createFromRoute($title,$routeName,$routeParameters,$options);

  return $links;
}

I was pretty close to hooking up with the code of menu_breadcrumbs but I think there is an issue with the code there that prevents this kind of use see issues/3026188

My code is still not perfect and I would really still want to find a way to access and chain the breadcrumbs of "parent" node(node/22) in a more general way.

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.