It appears this is not related to the issue as was assumed in (#1 - #11):
PathMatcher::isFrontPage() does not work for the default homepage if it contains a query string.
I have tested this with a small block that displayed the value of PathMatcher::isFrontPage()
, but it also appears to affect the menu system (where I first noticed this):
Issue since #12:
When appending a query string to a URL, the active trail is no longer added. This is undesirable because queries might be added for tracking a user's entrypoint eg example.com?referrer=email
or pagination on a page (the second page of the menu item is still in the active trail of the menu item).
These situations will make that you see the home page, but it is not marked as active.
Reproduce:
- Visit the regular front page of your Drupal site:
example.com
. - Append a query string to the url:
example.com?foo=bar
. - Notice that the home menu item no longer has the
is-active
class. - Then repeat the same test with JavaScript disabled in development console and not being logged in. Notice the same behavior.
I could only achieve above behavior with the home page (example.com?foo=bar
and example.com/node?foo=bar
) and all other paths work as expected, so there appears to be something wrong with this default front page path somehow.
This appears not to be only limited to the home page anymore. Appending a query string to other pages also makes they are no longer marked active.
Before:
After patch #42:
Comment | File | Size | Author |
---|---|---|---|
#85 | 2845319-85.patch | 3.35 KB | _utsavsharma |
#85 | interdiff_84-85.txt | 1.5 KB | _utsavsharma |
#84 | 2845319-84.patch | 2.88 KB | casey |
#80 | interdiff_79-80.txt | 716 bytes | juanolalla |
#80 | 2845319-80.patch | 2.65 KB | juanolalla |
|
Issue fork drupal-2845319
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 #3
dawehnerOne thing you could do is to try to write a test case.
core/tests/Drupal/Tests/Core/Path/PathMatcherTest.php
already contains a bunch of tests for this class.Comment #4
Neograph734I will have a look. Thanks.
Just to be sure, I first write a test that is supposed to fail, and then a patch so the test passes again right?
Comment #5
dawehnerThat would be ideal indeed.
Comment #6
Neograph734Right, I'll see what I can do.
Comment #7
Neograph734So I think that paths containing query strings or fragment identifiers should actually be considered equal to paths without. Attached patch adds checks for query strings and fragment identifiers. This one should fail.
Changed the name a little, since a local test turned out this was not strictly related to the front page.
Comment #9
Neograph734Hmm, after attempting to patch the above issue (by attempting to strip everything after the ? from the url). It appears this is not coming from
PathMatcher->matchPath()
.In fact, it seems that the PathMatcher including the
isFrontPage()
function are working as expected now. But the menu active trail is still not recognized.It seems to be even weirder though. The
is-active
class on the home menu-item is added later via JavaScript or something? The raw data from the page looks like this:But in Development console it looks like this:
There is also a quick flash on the menu item when loading a page. (All caches are disabled using this method: https://www.drupal.org/node/2598914)
Apparently this JavaScript (what else could it be) is only matching the exact url and does not take query parameters into account? Can someone confirm this?
Comment #10
Neograph734Comment #11
Neograph734Comment #12
Neograph734After disabling JavaScript in the Development Console, the home tab indeed no longer lights up. This means there is nothing in the menu system adding the class to "Home".
Which makes this related to #2641198: "Home" menu-item is missing li.menu-item--active-trail class and #1578832: Class active-trail not added to li element when linking to front page.
Comment #13
Neograph734This appears to be coming from the following line in core/misc/active-link.js:
If the is a query string provided in the url field, Drupal assumes that the query string should also exist on the link that rendered the page. All links to the same path, but without the query string will not get activated. In my opinion, this should look more like the following, where the selectors contain both versions, with and without query string:
But then in the end, it still feels very strange this needs to be done with JavaScript. I'd assume that the menu system would be capable of adding a class to a link.
Comment #14
Pavan B S CreditAttribution: Pavan B S at Valuebound commentedRerolled the patch, please review
Comment #16
Neograph734Thanks Pavan,
But the problem is not within the PathMatcher(). It is in 'core/misc/active-link.js'. See #13.
Comment #17
Neograph734Created the patch as proposed in #13.
Comment #18
Neograph734Comment #19
Neograph734Comment #21
Neograph734I am removing the 'needs tests' as this is not a core system failure, but just a wrong javascript selector. Let's see if the patch still applies.
Comment #22
danylevskyiComment #23
danylevskyiComment #24
Neograph734Yes, this seems to work!
Comment #25
xjmThanks @Neograph734 and @danylevskyi.
We do have the ability to write automated tests exercising JavaScript; see JavaScriptTestBase and https://www.drupal.org/docs/8/phpunit/phpunit-javascript-testing-tutorial. So, setting back to "Needs work" and re-tagging for an automated test to be written.
@Pavan B S, I've removed credit for the reroll in #14 because it was indicated in comments after #7 that it was no longer the correct approach. Please read the issue comments before submitting patches.
Comment #26
Neograph734@xjm, would it suffice to write a test that simply fetches
example.com?foo=bar
andexample.com?foo=bar&bar=baz
and then validates that the home tab is highlighted? Or should we include other cases as well (and which ones)?Comment #27
Neograph734I am a bit confused... In core/misc/active-link.es6.js the top reads the following:
So that means the current behavior would be the desired behavior.
Also my prior statement that this does only affects the 'Home' menu item is untrue. Exactly as the above description states the
is-active
class is only added to menu items with matching query parameters. However this is not visible at first glimpse as all other menu items do have themenu-item--active-trail
class, so they do appear with a highlighted menu tab.So I dug in the history of active-link.js and figured out that it was created as part of #1979468: ".active" from linkGenerator(), l() and theme_links() forces an upper limit of per-page caching for all content containing links. Short summary:
However, it seems that the caching problem has been resolved in MenuActiveTrail::getActiveTrailIds:
So if I understand everything well, we can conclude that active-link.js is effectively no longer needed because the menu-link--active-trail covers the same highlighting. (Removing it would involve a change record that themers should replace
is-active
withmenu-item--active-trail
?) Or we do implement the patch from #23, but then it should also be tested what happens if a menu item links to the second page of a paged view. It should not light up for the first page, as explained on the top.The actual issue is that the 'Home' menu item does not get the
menu-item--active-trail
class assigned because it is not considered to be part of the active trail.I would really like a maintainer to chime in here and share some thoughts on this before I start taking any more actions. Is there some tag to request maintainer feedback or something?
Comment #28
Neograph734I hope this is the right tag to draw some attention to this issue, for as I am stuck.
Comment #30
rahul01 CreditAttribution: rahul01 at QED42 commentedComment #31
rahul01 CreditAttribution: rahul01 at QED42 commentedComment #32
sumitmadan CreditAttribution: sumitmadan at QED42 commentedAdding to @Neograph734's comment, I'm not sure why it is implemented this way, but, adding an active class to link based on query parameters, seems a very rare case.
Also, patch in #23 resolves the issues for authenticated users only. For the anonymous user, "ActiveLinkResponseFilter" class is used to set "is-active" class to link.
Comment #35
RedLucas25 CreditAttribution: RedLucas25 at Advisor Websites commentedI also want to add to this that I think it is fair to expect the active-link to not be query string dependent.
It's been two years since this has been touched from the looks of it. I just now have run into an issue that is resolved by #23. (authenticated user problem).
I'll be implementing the patch, but I'd much prefer about seeing a solution make it into core.
Comment #37
imot3k CreditAttribution: imot3k commentedRe-rolled patch against 9.2.x.
Comment #38
ankithashettyJust fixing the custom command failure errors in #37, thanks!
Comment #39
ankithashettyFixing the custom command failure errors, thanks.
Comment #40
Yago Elias CreditAttribution: Yago Elias as a volunteer and at CI&T commentedPatch #39 worked for me on Drupal 9.1.7.
Links are now highlighted when accessing the page with a query string.
Comment #41
Yago Elias CreditAttribution: Yago Elias as a volunteer and at CI&T commentedChanging status of the to RTBC.
Comment #42
jungleRe #39, .js files should be generated by running the following commands:
I am afraid this one would not get committed without tests added as this is a bug, tagging back Needs tests. Also tagging Bug Smash Initiative. The current active dev version is 9.3.x-dev.
Comment #43
Gauravvvv CreditAttribution: Gauravvvv at OpenSense Labs commentedNow is-active class is available after using ?foo=bar after the URL on the homepage.
I have added before and after patch screenshot for reference.
Moving to RTBC.
Comment #44
Gauravvvv CreditAttribution: Gauravvvv at OpenSense Labs commentedUpdated IS
Comment #45
xjmCommitters do not monitor the "Needs committer feedback" tag, so no use adding it. :) (You probably figured that out since no one replied for years.) We monitor tags for our individual roles ("Needs release manager review", etc.), or the RTBC status.
This seems a reasonable change to me; however, we still need test coverage for it. (The manual testing and screenshots were helpful! But we also need an automated test.) It's also worth noting that (as described in #27), this sounds like it was working as documented. If we're changing the behavior to allow any query string to be highlighted, should we also update the docs?
Thanks!
Comment #46
Neograph734@xjm, I had figured something by now :). But thanks for at least confirming that the proposed behavior makes sense. If a query string is used in pagination for a second 'page' on the home page, I suppose it is still the home page.
When searching for the test, I also ran into
ActiveLinkResponseFilter
. And I think that might need updating as well (as well as its testActiveLinkResponseFilterTest
). This class is actively checking if the query matches with the element'sdata-drupal-link-query
attribute, which might not be defined.After disabling Javascript in the developer console, the behavior can be observed so there is is also a non-javascript part adding the is-active class for anonymous users too! (Summary updated.)
As for test of the active-link.js JavaScript, I cannot seem to find any existing test?
Comment #47
Neograph734Comment #50
bnjmnmComment #51
jenlamptonUpdating issue title.
Comment #52
nod_Comment #53
juanolalla CreditAttribution: juanolalla at Jeneration Web Development commentedThis needs a reroll, core/modules/system/tests/src/Functional/Common/UrlTest has changed: "Merge blocked: fast-forward merge is not possible. To merge this request, first rebase locally."
Comment #54
juanolalla CreditAttribution: juanolalla at Jeneration Web Development commentedRerolled merge request. Attaching updated patch.
Comment #57
Drumanuel CreditAttribution: Drumanuel commentedPatched 9.4.2 with 2845319-54.patch, looks good
Comment #58
Abhijith S CreditAttribution: Abhijith S as a volunteer and at Srijan | A Material+ Company for Drupal India Association commentedApplied MR 866 on 9.5.x and it works fine.The
is-active
class is appearing even when the query strings are present, after applying this patch.Before patch:
After patch:
Comment #59
Neograph734Setting RTBC based on #56 and #57. Thanks for testing.
Comment #60
balazswmann CreditAttribution: balazswmann commentedI can also confirm that the patch in #54 works with 9.3.21. Thanks!
Comment #61
Gauravvvv CreditAttribution: Gauravvvv at Srijan | A Material+ Company for Drupal India Association commentedComment #62
alexpottThere are some suggested changes from @bnjmnm and also we will need a 10.x version of the MR because there are no longer .es6.js files and JS standards have been tweaked slightly no we don't have to support IE.
Comment #64
Artusamak#54 reroll for 9.5.x.
Comment #65
_utsavsharma CreditAttribution: _utsavsharma at OpenSense Labs for DrupalFit commentedFIxed CCF for #54 for 9.5.x.
Please review.
Comment #66
gidarai CreditAttribution: gidarai at Finalist commentedComment #67
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #68
Gauravvvv CreditAttribution: Gauravvvv at Axelerant for Drupal India Association commentedAdded patch for 10.1.x. please review
Comment #69
Gauravvvv CreditAttribution: Gauravvvv at Axelerant for Drupal India Association commentedFixed CCF, attached interdiff for same.
Comment #70
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #71
douggreen CreditAttribution: douggreen at Peak Digital, LLC commentedThis line needs parenthesis to clarify the logic:
But really what it needs is simplification IMO, maybe something like:
Comment #72
Nitin shrivastava CreditAttribution: Nitin shrivastava at OpenSense Labs commentedTry to fix error.
Comment #73
douggreen CreditAttribution: douggreen at Peak Digital, LLC commentedHaving a merge request and the patch is confusing. I've tried to sort out which is newer, I think that the patch is newer. The merge of 9.3.x by @Juan and the merge of 9.5.x by me complicate the history. I suggest that we start over with the current patch 72.
The attached patch
Comment #74
juanolalla CreditAttribution: juanolalla commentedIn #54 patch I just re-rolled the merge request, I don't know who/when/why that logic changed in ActiveLinkResponseFilter.php at some point. As long as ActiveLinkResponseFilterTest.php is testing the logic well and the patch passes tests we are fine.
#73 patch is failing to apply. Does it target 10.1.x?
Comment #75
douggreen CreditAttribution: douggreen at Peak Digital, LLC commented#73 is for 9.x
Here is a patch for 10.x (the primary change is [#3305487], but this needs review to ensure I resolved the conflicts properly).
Comment #76
Akram Khanadded updated patch and fixed CCF of #75
Comment #77
Akram Khanfixed CCF #76
Comment #78
juanolalla CreditAttribution: juanolalla commentedI'm uploading a new patch with just the changes to active-link.js. I think this is going to pass tests, and I'll explain why.
I'm removing the changes to ActiveLinkResponseFilterTest and UrlTest. They fail because there is no related implementation on php, which is what they are testing. They are testing the logic in ActiveLinkResponseFilter, that hasn't change at all. So it make no sense to change the testing logic without changing the code being tested.
So, as we have seen from the beginning, there are different places where the logic that states that a URL with query parameters is not the same as without or different query parameters in terms of marking links as "active", has been implemented, on the backend code, and with JavaScript. We are fixing this just in the JavaScript layer, and with that change, tests don't fail. That means that there is no JavaScript tests in core right now checking that the links shouldn't have the 'is-active' class when not matching query parameters.
So, to do this right, in my opinion, we should discuss if we are agreed that the current logic is not right: all same url with different query parameters combinations (with the same language), should be treated as the same in terms of marking is as active.
Then, if we agree on that and this issue makes sense, we should create JavaScript testing cases for the new logic (there isn't any for the current logic at this level).
And then, we should rewrite the PHP code as well, and so for the tests managing that. Why do we have both PHP and JavaScript implementation? I would love to know.
Comment #79
bnjmnm#78 looks good - this just gets rid of a bit of repetition and
concat()
uses.Comment #80
juanolalla CreditAttribution: juanolalla commentedPatch #79 wasn't working, the is-active stopped appearing (and tests failed). JSON.stringify() was adding double quotes, so we ended up having double quotes within double quotes in the queryMatchSelector string variable.
Fixed in this patch #80. Adding interdiff.
Comment #82
douggreen CreditAttribution: douggreen at Peak Digital, LLC commentedThe test form earlier patches was lost, and need to be restored.
Comment #83
juanolalla CreditAttribution: juanolalla at Peak Digital, LLC commented@douggreen please see #78 above, where I explained the problem I found with tests (tldr: wrong tests, js tests don't exist yet for this in core)
Comment #84
casey CreditAttribution: casey as a volunteer and at SWIS commentedJust run into this issue as well. What about only checking the query arguments from data-drupal-link-query and only skip if any of those don´t match the current query, while ignoring any additional query arguments from the current query.
Comment #85
_utsavsharma CreditAttribution: _utsavsharma at OpenSense Labs for DrupalFit commentedTried to fix the CCF in #84.
Comment #87
John Pitcairn CreditAttribution: John Pitcairn commentedUsing patch #80 against 10.2.3 allows local task tabs to highlight as active if there is any added url query.
I have not tested what happens if the local task target url itself contains a query. In that case the behaviour should probably be to match the local task specific query parameter(s) and only highlight as active if the task url query parameters match, ignoring added query parameters. @casey is this what #84 is attempting?