Problem/Motivation

When non-ASCII characters are used in the query string of a Url object, the link generator service fails to add an is-active class to the anchor tag.

Steps to reproduce

This faulty behavior is demonstrated by the test-only changes in the MR. The MR modifies the core LinkGeneratorTest::testGenerateActive() test to demonstrate that this test passes when an ASCII query string is used but fails with a Cyrillic query string.

Proposed resolution

Post #8 proposed a change to the JavaScript that adds this class.

Remaining tasks

Fix the link generator service so that the tests pass. #8 needs to be put into the MR and reviewed, or another change needs to be proposed.

User interface changes

None.

API changes

None.

TL;DR

The constructor for \Drupal\Core\Url allows the user to pass in an array of key-value options as the third parameter.

These options are supposedly documented in the documentation for Url::fromUri() but in practice core sets and uses other options that are not documented there.

Specifically, the link generator service recognizes and uses the set_active_class option. This option is documented in core/includes/theme.inc in the documentation for template_preprocess_links() (deprecated, moved to an OO hook \Drupal\Core\Theme\ThemePreprocess::preprocessLinks).

- set_active_class: (optional) Whether each link should compare the
     route_name + route_parameters or URL (path), language, and query options
     to the current URL, to determine whether the link is "active". If so,
     attributes will be added to the HTML elements for both the link and the
     list item that contains it, which will result in an "is-active" class
     being added to both. The class is added via JavaScript for authenticated
     users (in the active-link library), and via PHP for anonymous users (in
     the \Drupal\Core\EventSubscriber\ActiveLinkResponseFilter class).


There are also core test cases in \Drupal\Tests\Core\Utility\LinkGnereatorTest to ensure this option does the right thing.

Original bug report

Code:

        \Drupal::service('link_generator')->generate($title, Url::fromRoute('yarcom_sphinx.search_type', array('search_type' => $t), array(
          'set_active_class' => TRUE,
          'query' => array(
            'q' => $i['query'],
          ),
        )));

If $i['query'] is russian characters, css class is-active does not appear.

Example 1:
$i['query'] = 'комацу' (russian characters).
Browser address bar: http://dev.******.ru/search/yarcom_news?q=%D0%BA%D0%BE%D0%BC%D0%B0%D1%86...
Html code:
<a href="/search/yarcom_news?q=%D0%BA%D0%BE%D0%BC%D0%B0%D1%86%D1%83" data-drupal-link-query="{&quot;q&quot;:&quot;\u043a\u043e\u043c\u0430\u0446\u0443&quot;}" data-drupal-link-system-path="search/yarcom_news">News entity</a>

Example 2:
$i['query'] = 'komatsu' (english characters).
Browser address bar: http://dev.*****.ru/search/yarcom_news?q=komatsu
Html code:
<a <strong>class="is-active"</strong> href="/search/yarcom_news?q=komatsu" data-drupal-link-query="{&quot;q&quot;:&quot;komatsu&quot;}" data-drupal-link-system-path="search/yarcom_news">News entity</a>

In the first example q=%D0%BA%D0%BE%D0%BC%D0%B0%D1%86%D1%83" and data-drupal-link-query="{"q":"\u043a\u043e\u043c\u0430\u0446\u0443"}" are not identical.

Issue fork drupal-2525830

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

cilefen’s picture

Title: The error in the coding of the parameters url » Url::fromRoute does not understand Russian characters in the query option
Issue tags: -LinkGenerator, -generate, -query
dawehner’s picture

.

tr’s picture

комацу must be urlencoded to put it in a URL.
%D0%BA%D0%BE%D0%BC%D0%B0%D1%86%D1%83 is the correct urlencoding.
Browsers will display the Cyrillic characters instead of the urlencoded characters, but if you look at your server logs you will see that when you type http://dev.******.ru/search/yarcom_news?q=комацу into your brower
the server actually receives http://dev.******.ru/search/yarcom_news?q=%D0%BA%D0%BE%D0%BC%D0%B0%D1%86...

The string \u043a\u043e\u043c\u0430\u0446\u0443 is also equal to комацу, but it is written with Unicode escape characters instead of urlencoding. So I don't see anything wrong with Example 1.

The only bug I see here is "If $i['query'] is russian characters, css class is-active does not appear.". I have not tried to reproduce that yet.

Sky Cat’s picture

So I don't see anything wrong with Example 1.

The problem is just that the class is not set "is-active" if the query contains the Russian characters.

tr’s picture

Yes, that's what I said:

The only bug I see here is "If $i['query'] is russian characters, css class is-active does not appear.". I have not tried to reproduce that yet.

dawehner’s picture

Component: routing system » system.module

This problem is not a routing problem ....

pwolanin’s picture

Status: Active » Postponed (maintainer needs more info)
Related issues: +#2809789: UrlGenerator fails to urlencode aliases, incorrectly encodes "system" path

possibly related to #2809789: UrlGenerator fails to urlencode aliases, incorrectly encodes "system" path but if this is about the search query string this is specific to search module not system module?

Does this bug still occur? Please set back to active if it does (or post a test patch)

Sky Cat’s picture

The problem in function system_js_settings_alter(), file - system.module.

When the $current_query->q duplicate $current_path, in the file active-link.js variable takes the value path.currentQuery.
The array activeLinks becomes empty.

Current query:
'q' => string(17) "weather/yaroslavl"

Current path:
string(17) "weather/yaroslavl"

misc/active-link.js:
var activeLinks = context.querySelectorAll(selectors.join(','));
is empty.

Problem in string
var querySelector = path.currentQuery ? "[data-drupal-link-query='" + queryString + "']" : ':not([data-drupal-link-query])';

If the code is changed to

var querySelector;
// encodeURI() for non-latin symbols.
      if (typeof path.currentQuery && encodeURI(path.currentQuery.q) == path.currentPath) {
        querySelector = ':not([data-drupal-link-query])';
      }
      else {
        querySelector = "[data-drupal-link-query='" + queryString + "']";
      }

class is-active will be added

pwolanin’s picture

Version: 8.0.0-beta12 » 8.3.x-dev

Please confirm that the bug exists in 8.3.x

I'd need to look at the JS but the proposed fix looks simple - can you make that as a patch?

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.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.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.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.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.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.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.

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.

pameeela’s picture

@Sky Cat thanks for reporting this issue. We rely on issue reports like this one to resolve bugs and improve Drupal core.

As part of the Bug Smash Initiative, we are triaging issues that are marked "Postponed (maintainer needs more info)".

Are you able to advise whether this issue is still occurring? If so, are you able to post a patch with the change you proposed in #8?

tr’s picture

Status: Postponed (maintainer needs more info) » Active
StatusFileSize
new1.08 KB
new1.07 KB

This is still an issue, and it's easy to confirm - maybe this 5-year old bug and all the others like it can actually get help and contribution from the community, instead of being shut down for lack of activity?

Here are two trivial patches to demonstrate the problem. They both change the core LinkGeneratorTest.

The first patch changes a test case so that the query parameter is 'комацу' - this test case does exactly what is shown in the original post, and this test case will now fail using Cyrillic characters in the query string.

The second patch changes that same test case in the same manner, this time using the query parameter 'komatsu' - this test case also does exactly what is shown in the original post, but this time it passes because ASCII characters were used.

I present two patches so you can see that the test failure with the first patch was not due to me modifying the test the wrong way - the only difference between the two patches is that one uses 'комацу' and the other uses 'komatsu'.

Oh, and before someone complains about the patch looking bad in the browser, that's because Drupal.org STILL serves up patch files using a text encoding of 'windows-1252', which doesn't properly display Russian characters like this. But if you download the patch and look at it you will see it is correct. This was reported three years ago in #2922638: No charset on response for patch & text files

pameeela’s picture

@TR thanks for confirming. I’m sure you know that the best way to get this resolved is to post a patch with a fix.

If you or someone else posts a patch, I will try to expedite review via the bug smash initiative.

maybe this 5-year old bug and all the others like it can actually get help and contribution from the community, instead of being shut down for lack of activity?

I am not sure exactly what you mean but I assure you that no one is trying to shut down issues. I am glad that by following up on this ticket that we are now more likely to progress it thanks to the info and test patches you have posted.

larowlan’s picture

Issue tags: +JavaScript
pameeela’s picture

Issue tags: +Bug Smash Initiative

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.

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.

mstrelan’s picture

This needs an issue summary update, let's start with the standard issue template. I think it's also not clear from the title what is the bug that needs fixing, i.e. the is-active class is not added. Let's get 2525830-18-комацу.patch converted to an MR so we can see the test fail, then we can work on a fix for this.

tr’s picture

Test-only patch from #18 still applies. The test results in #18 demonstrated the bug for many years, until patch testing got turned off.

Here is the patch again in a merge request.

mstrelan’s picture

The test results in #18 demonstrated the bug for many years, until patch testing got turned off.

I'm not disputing that, just trying to help make it easier for anyone interested in picking this up. Without this it's hard to know at a glance if anything has changed in core that might have fixed this over the last 5 years.

tr’s picture

Title: Url::fromRoute does not understand Russian characters in the query option » LinkGenerator does not generate is-active class when Russian characters are used in the query option
Issue summary: View changes
Issue tags: -JavaScript, -Needs issue summary update +JavaScript

Updated issue summary.

mstrelan’s picture

Issue tags: -JavaScript +JavaScript

Thanks for updating this. I'm still confused about the steps to reproduce. If I understand correctly from #3 and #8, the HTML output is correct and the JS needs to be updated. The proposed resolution is to make the Unit test pass, but that's contradictory to the above. We probably need a FunctionalJavascript test instead. I note that we now have \Drupal\Tests\system\FunctionalJavascript\ActiveLinkTest which seems like a good place to test this. I tried to follow the suggestion in #8 but active-link.js has changed quite a bit so it wasn't straight forward.

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.