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="{"q":"\u043a\u043e\u043c\u0430\u0446\u0443"}" 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="{"q":"komatsu"}" 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.