Problem/Motivation

Working in a custom module I need to alter the breadcrumb for some cases and I use hook_system_breadcrumb_alter(). But I noticed I can't remove a Link from the breadcrumb using the methods ::getLinks() and ::setLinks() because of the logicException in the method ::setLinks() of the same class:

Once breadcrumb links are set, only additional breadcrumb links can be added.

I don't get the reason behind this. Is it cache? Can we have a method in the Drupal\Core\Breadcrumb\Breadcrumb class for this purpose? Or at least explain in the exception a bit more about the reasons this can't be done. I just tried this one that I attached using a comparison between route names and works as I expected.

Steps to reproduce

Call Breadcrumb::setLinks() on a Breadcrumb object that already has links.

Proposed resolution

  • Create ::removeLink()
  • Remove the logicException in ::getLinks()

Remaining tasks

Agree on what to do. Implement. Possible code is in the merge request. Tests are needed.

User interface changes

None.

Introduced terminology

None.

API changes

It will be possible to remove links from a Breadcrumb object.

Data model changes

None.

Release notes snippet

Issue fork drupal-2966004

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

nachosalvador created an issue. See original summary.

cilefen’s picture

Version: 8.5.x-dev » 8.6.x-dev
chanderbhushan’s picture

@cilefen, I have tested your patch its working fine.

rodrigoaguilera’s picture

Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Needs tests

@chanderbhushan Thank you for taking the time to test it.

I think the method should be called removeLinkByRouteName(string $routeName) as this the real behaviour of the method.
The logic should be changed accordingly.

rodrigoaguilera’s picture

This is the issue were that method was introduced

#2483183: Make breadcrumb block cacheable

prashant.c’s picture

Status: Needs work » Needs review
StatusFileSize
new232 bytes
new840 bytes

@rodrigoaguilera

I don't think the function name should be changed as to keep the consistency in the function name setLinks() addLink()
we should keep it as removeLink.

Made a minor addition to the function description.

lauriii’s picture

rodrigoaguilera’s picture

My only reasoning behind changing the name is to keep the functionality of using a route to delete a link in the breadcrumb (it can actually delete many links that use the same route).

A function called removeLink that accepts a link as a parameter should make a more strict comparison other than the route name.

I feel we should choose a path here. whether a real removeLink() method is added that removes exactly the link that you pass or we remove the link using the route name with a change in the method name.
Leaving it as is is a bit confusing.
My opinion is that we should add the ability to remove a link using a route name.

berdir’s picture

Would also need to investigate why it is like this, but definitely +1, I've had this use case more than once and you currently have to get the links and create a completely new breadcrumb object, in which it is easy to forget adding the existing cacheablity metadata.

borisson_’s picture

Also +1 on the idea, this seems like a great idea. We still need those tests though. I guess we should wait on the subsystem maintainer review before adding those tests.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

arijits.drush’s picture

StatusFileSize
new913 bytes

We faced issue which #8 suspected before, if we have more than 1 contextual filter in a view then matching only route removes all links of the view from breadcrumb.
Submitting patch which checks for route + parameter with its order.

rodrigoaguilera’s picture

Status: Needs review » Needs work

I think it looks better now with additional checks.

Still needs tests and a subsystem maintainer review

avpaderno’s picture

Title: Add possibility to remove a link from breadcrumb » Add possibility to remove a link from breadcrumbs
Issue tags: -breadcrumb +breadcrumbs
dawehner’s picture

I was looking at the existing breadcrumb class, it's certainly not a pure value object by any form of standard.
It looks like originally the exception got introduced to avoid weirdnesses with the cacheability metadata, see https://www.drupal.org/project/drupal/issues/2483183#comment-10216507 , but it's funny that you get the same problem when creating your new object as well.

When adding a removeLink method I wonder whether you'd run into some issues as well.

In general my gut feeling somehow would have suggested a filter method instead, given that it might be tricky to know exactly which link you want to remove. Equality of links in this patch is provided by route + route parameters, but there is still the title involved as well. Using a filter method, you would move this responsibility to the caller.

spadxiii’s picture

StatusFileSize
new742 bytes

Added a small patch (based on 8.7.x) that adds a filterLinks method to the Breadcrumb class. It accepts a callable, which is used to array_filter the items. The callable gets both the link and the key of each breadcrumb-item.

It still needs tests, so I'll leave the issue on 'needs work'

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ivnish’s picture

#13 works

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

nachosalvador’s picture

I've faced this issue again and I've created my own Breadcrumb builder as a workaround.

Hope it helps to someone :)

liam morland made their first commit to this issue’s fork.

liam morland’s picture

Status: Needs work » Needs review

I made a merge request with the patch in #13 plus adding the ability to use ::setLinks() when the links are not empty. Before making tests, I perhaps a maintainer could approve the direction of this.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update

Issue summary appears incomplete

Also think test coverage could be expanded to test calling the removeLink function.

liam morland’s picture

Issue summary: View changes
Issue tags: -Needs issue summary update

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.