Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
\Drupal\Core\Menu\LocalTaskManager::getLocalTasksForRoute
is not optimal at the moment
Proposed resolution
Improve it by extracting things into dedicated methods which have each proper documentation. This itself is worth it
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#61 | interdiff_59-61.txt | 926 bytes | Ratan Priya |
#61 | 2653144-61.patch | 15.85 KB | Ratan Priya |
#59 | 2653144-59.patch | 15.85 KB | smustgrave |
| |||
#59 | interdiff-56-59.txt | 1.75 KB | smustgrave |
Issue fork drupal-2653144
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
Comment #2
dawehnerThere we go.
Comment #3
Crell CreditAttribution: Crell at Palantir.net for Acquia commenteddawehner++
I would structure this differently. Rather, we want a getLocalTasks() method, which internally is just a caching/memoizing wrapper around a generateLocalTasks() method (or similar). Then just use the get method when we actually need it, and the caching all happens behind the scenes.
This would be clearer as an array_filter call, followed by an array_map. (Mainly because that encourages breaking off defined, named methods for what the filter criteria are and what we're actually doing with it.)
I do not fully understand the purpose of this code, but the comment is enough to make me curl up in a ball in fear. Modify information for the next foreach iteration? Er... that sounds highly scary.
Comment #4
dawehnerWell, you would need an
array_walk()
if you actually have to implement it, see+ $children[$parent][$plugin_id] = $task_info;
Well, its how you can iterate over trees without function calls.
Maybe something like that?
Comment #7
pwolanin CreditAttribution: pwolanin as a volunteer commentedInternal re-org seems fine, if you have the energy
Comment #8
dawehnerWell yeah, I think its doable and well, the current code in HEAD is indeed hard to grock.
Comment #11
grathbone CreditAttribution: grathbone as a volunteer commentedRefactored the existing code. In the process, I took care of the @todo to allow for more than 2 levels of routes.
In explanation
Benefits of refactoring, using tree, and caching the children:
Two questions though:
Let me know what you guys think.
Comment #12
grathbone CreditAttribution: grathbone as a volunteer commentedComment #14
grathbone CreditAttribution: grathbone as a volunteer commentedRe-rolling the patch. Updated the documentation. Please see https://www.drupal.org/node/2653144#comment-12084135 for original comment.
Comment #15
grathbone CreditAttribution: grathbone commentedComment #17
dawehner@grathbone I'm highly confused. This is about the
LocalTaskManager
, but you refactor something about breadcrumbs. Is there some misunderstanding on my side what is going on?Comment #18
grathbone CreditAttribution: grathbone as a volunteer commented@dawehner That's my fault for reusing terminology. The thought is that it checks the route that is passed in, and parses through the plugin definitions for that route's parent plugin definition IDs (breadcrumbs). This way, it can use the parent plugin IDs (breadcrumbs) to then move down the local task menu tier by tier to allow more than first and secondary menus (to take care of the @todo that has been in there for a while.) This additionally lets modules to continue to show active path in first and secondary menus without necessarily having the current page on a visible local task.
In doing so, I attempted to also refactor the class to break out certain methods and make it more readable.
Here is a new patch. Note: I undid the part about caching children and made some updates since the last patch.
Comment #20
grathbone CreditAttribution: grathbone as a volunteer commentedThese tests aren't failing locally, so here's another shot in the dark. I'm currently trying to determine why Drupal\Tests\system\Functional\Menu\MenuAccessTest erred, since the message response is accurate (that the link exists).
Comment #22
grathbone CreditAttribution: grathbone as a volunteer commentedSo this patch addresses two issues: refactoring the code class to make it easier to manage, and taking care of the @todo to allow more than two levels of depth.
Changes
It set up 3 new methods on the LocalTaskManager test:
I modified one test, LocalTaskManagerTest, to change the test cached response.
Possible changes
@dawehner, I could change getBreadCrumbsForRoute to getActiveTrailForRoute.
Also, I considered setting up a method getTreeByActiveTrail to create the task tree from passed-in $definitions and $activeTrail, to make this class more reusable, and then removing generateChildrenForDefinitions.
Comment #23
dawehnerThat sounds like a better name, given that breadcrumb is already a word in the domain of menus.
One question: Is there reason this method is public?
Comment #24
grathbone CreditAttribution: grathbone as a volunteer commentedModified a bit and renamed to active trail.
@dawehner My thought is so that these methods could be used elsewhere, I.E. if someone would want use the manager in their own module/block/alter to load different definitions, modify the active trail, or use a full menu-tree setup (nested unordered lists) compared to the multi-level (first, secondary) setup that local tasks currently uses by default.
Comment #25
dawehner@grathbone
Sure, but well, there is something like a BC break if we add new methods to an existing interface. This is not for free, and the discussions with the committers can take time. We can always iterate in another issue and make it public, but to avoid friction its better to keep it as it is, for now.
Please also keep in mind to post interdiffs as it makes it easier, at least for me, to follow along what you change.
Comment #27
grathbone CreditAttribution: grathbone as a volunteer commented@dawehner Oh, alright. I modified the methods and made them protected and removed them from the interface class. Also, sorry about that; I'm new to contributing and I'm still getting the hang of testing and creating patches. Thanks for sending over the interdiff link!
I made an interdiff between the last patch that passed (#22) and the new one.
Comment #28
grathbone CreditAttribution: grathbone as a volunteer commentedComment #29
dawehnerHey, no worries. I'm more than happy you try to tackle this bit of tricky code. I'm just a modest helper for you.
@grathbone
One next great step someone could do is to update the issue summary to describe what kind of refactorings got applied. This helps reviewers to know exactly what is going on.
Comment #32
grathbone CreditAttribution: grathbone as a volunteer commentedRerolled for 8.6.
Comment #33
borisson_There is a couple of coding standards issues in the patch.
Those should be fixed, I'd love otherwise RTBC this patch but I don't feel sufficiently sure about this, it looks like this breaks the current behavior, because the test also needed to be changed.
Back to needs work for those coding standards.
Comment #34
yogeshmpawarComment #35
yogeshmpawarCoding standard issues are solved in updated patch mentioned in #33 & also added an interdiff.
Comment #44
smustgrave CreditAttribution: smustgrave at Mobomo commentedComment #45
akshay_dWorking on this issue
Comment #46
akshay_d#35 apply cleanly to 9.5.x.
Added the screenshot after applying please review and let us if anything else needs to be updated.
Thanks
Comment #47
borisson_Thank you for reviewing this issue @akshay_d
The automated testing infrastructure tells us whether the patch applies, so we do not need people to review that, and also not needed to post a screenshot for that.
What we do need people to review is whether the issue has a correct scope, whether it passes the core gates, whether the solution completely fixes the problem without introducing other problems, and whether it's the best solution we can come up with. See the patch review guide for more information.
When you do post a review, be sure to describe what you reviewed and how, this helps other reviewers.
Comment #48
pooja saraah CreditAttribution: pooja saraah at Srijan | A Material+ Company for Drupal India Association commentedAttached Reroll patch against Drupal 9.5.x
Comment #49
Ankit.Gupta CreditAttribution: Ankit.Gupta at Dotsquares Ltd. commentedRerolled patch #35 with Drupal 9.5.x
Comment #50
Ankit.Gupta CreditAttribution: Ankit.Gupta at Dotsquares Ltd. commentedRerolled patch #49 with Drupal 9.5.x
Comment #52
joachim CreditAttribution: joachim at Factorial GmbH commentedThis looks like a useful thing to do -- smaller and simpler methods are easier to understand, debug, and maintain!
However, the docs aren't clear in places.
I'm also concerned that the tests are being changed in this patch. If this is just a refactoring, then tests should not change -- instead, they should remain the same to show us they still pass and so the functionality is unchanged by the refactoring!
This would be a great place to explain what the active-trail means.
Also, if there is a $route_name parameter, then it's not the 'current' route, it's the 'given' route.
This needs to say the key is expected.
This needs more detail.
Should be 'Builds'. Same for all the other methods.
What's 'active_trail'?
Missing blank line.
Same - given route, not current route.
Comment #53
smustgrave CreditAttribution: smustgrave at Mobomo commented@Ankit.Gupta and @pooja saraah
You can check for build errors make sure to run
./core/scripts/dev/commit-code-check.sh
before uploading a patch to make sure there are no issues with code formatting. see https://www.drupal.org/docs/develop/development-tools/running-core-devel...@Ankit.Gupta
Please upload an interdiff so we can see the changes being made between patches.
Fixed up the patch. Attempted to address the points in #52 but sure it will need tweaking. Tech writing is not my strongest.
Comment #54
catchJust nits:
I don't know what (specific task definition plugins) means - I think this should move under the summary with a bit more detail.
array_key_exists() should be fully qualified (\array_key_exists()) for performance - PHP has an opcode implementation.
We could reverse the sentence to remove the parentheses:
If the definition isn't the parent of itself, add a definition pointer to the parent's child array.
I think this should be 'upwards'? Not entirely sure if that's a British vs. Americanism though.
Same thing with array_key_exists()
One more question - there's some test coverage changes, is that definitely all additions, or is it changing the expectations of the test. Would be good to have a 'patch only patch' to see whether it doesn't break the existing test coverage without those changes.
Comment #55
catchComment #56
smustgrave CreditAttribution: smustgrave at Mobomo commented#54
1 = Updated with a more clear version from a previous patch
2 = updated both instances
3 = Updated
4 = not sure I follow
5 = Updated
Also uploading test-only patch.
Comment #58
larowlanDrive by review, but we should be able to add type-hints to the new functions - both for the params and the return types
Comment #59
smustgrave CreditAttribution: smustgrave at Mobomo commentedUpdated with typehints.
Comment #60
BramDriesenRE #56 4. was about the word
upward
in the comment here. Which needs to be changed toupwards
I guess.Comment #61
Ratan Priya CreditAttribution: Ratan Priya at OpenSense Labs for DrupalFit commented@BramDriesen,
Made changes according to #60.
Needs review.
Comment #62
BramDriesenSee error below for the failed test run.
Comment #66
bharath-kondeti CreditAttribution: bharath-kondeti as a volunteer and at Specbee commentedAddressed #62 and Raised an MR. Please review.
Comment #67
bharath-kondeti CreditAttribution: bharath-kondeti as a volunteer and at Specbee commentedComment #68
smustgrave CreditAttribution: smustgrave at Mobomo commentedComment #69
BramDriesen