Problem/Motivation
In layout_builder_system_breadcrumb_alter() it assumes that all links are routable. However, breadcrumbs happily supports external links as well. When a non-routable link is encountered in that function the URL class will throw "UnexpectedValueException: External URLs do not have an internal route name".
Proposed resolution
Wrap the call to Url::getRouteName() with a check against Url::isRouted first.
Remaining tasks
Patch needed.
User interface changes
None.
API changes
None.
Data model changes
None.
Steps to reproduce
- Enable layout_builder module
- Check 'Use Layout Builder' from 'Layout Options' for a specific content type from its manage display settings page, for example for 'article' from /admin/structure/types/manage/article/display
- Then you have to open the page where you manage the layout via the layout builder from the 'Manage layout' button in the content type's 'manage display' page. For example for article from '/admin/structure/types/manage/article/display/default/layout'
I wasn't sure how to add an external link to the breadcrumbs via the UI, so I did it programmatically by adding two lines at the very top of layout_builder_system_breadcrumb_alter function inside of 'layout_builder.module'
$external_link = $link = Link::fromTextAndUrl('External link', Url::fromUri('http://www.example.com'));
$breadcrumb->addLink($external_link);
| Comment | File | Size | Author |
|---|---|---|---|
| #22 | interdiff_20-22.txt | 706 bytes | raman.b |
| #22 | 3090941-22.patch | 3.46 KB | raman.b |
| #20 | interdiff_17-20.txt | 2.35 KB | raman.b |
| #20 | 3090941-20.patch | 3.57 KB | raman.b |
| #17 | interdiff_12-17.txt | 2.69 KB | raman.b |
Comments
Comment #2
tim.plunkettOh, that's a really good point! Good find.
Comment #3
tim.plunkettTentatively tagging for novices. Please find me on Drupal Slack if you need guidance!
Comment #4
kris_nikolov commentedI am currently trying to do a first time contributation at Drupalcon Amsterdam 2019, and will have a look at this.
Comment #5
kris_nikolov commentedComment #6
kris_nikolov commentedChecked to see if the URL has a Drupal route first, before calling getRouteName() on it.
Comment #7
kris_nikolov commentedComment #8
dinesh18 commented#6 looks good to me, it uses Url::isRouted which returns bool and Indicates if this Url has a Drupal route.
@breakfull , can you provide me steps how can I test it ?
Comment #9
kris_nikolov commentedComment #10
kris_nikolov commented@Dinesh18 Updated the issue's description with 'Steps to reproduce'
Comment #11
rwohlebThe patch in #6 should always return a bool from the anonymous function even when it's not a routed link. Otherwise looks good to me.
Comment #12
jmdeleon commentedSmall fix to patch in #6, incorporating the suggestion in #11.
Comment #13
amd.miriAlternative solution/code.
Comment #14
tim.plunkettNW for tests
Comment #17
raman.b commentedAdding some test coverage to demonstrate the reported bug
Comment #19
tim.plunkettThanks! A couple small nits, and then I think this is ready.
Can this be swapped?
Adding
if (!isRouted()) { return TRUE; }as a guard condition makes more sense to me. Returning TRUE at the end reads confusingly to me.No need for a local variable
What is this moving to be after? Please add that as an inline comment.
Comment #20
raman.b commentedThanks for the review!
Addressing the pointers from #19
We need to move our
hook_system_breadcrumb_alterimplementation beforelayout_builder_system_breadcrumb_alter. Should we be more explicit about this? Currently we are moving before all the implementationsComment #21
tim.plunkettI don't know that this comment is valuable, and I'm tempted to remove it. If you think it's worth keeping, then it should be outside the
if()and should be one sentence. But to me "Check if the URL has a route before checking the route name" isn't helpful.This is perfect, thanks!
Comment #22
raman.b commentedSeems reasonable to get rid of it. We have several similar instances across core
Comment #23
joseph.olstadFinally found this patch, we totally need to fix this... we just made a sandbox module called cms_breadcrumbs for leading external breadcrumbs, and we need an external link in our breadcrumbs
Lets get this patch in asap, what is left to do?
I will be testing this patch on D8.9.x
Comment #24
joseph.olstadGreat fix, tested on D8.9.x , same patch applies (with fuzz and some .orig files leftover, but applies cleanly)
Comment #27
catchCommitted/pushed to 9.2.x and cherry-picked to 9.1.x, thanks!
Comment #28
joseph.olstadThanks @catch and everyone above, team work!