User tests: Successful: Unsuccessful:
This is a code review of the "Language Switcher" module (mod_languages).
The main objective was stricter adherence of the generated links to those generated by the Language Filter for rel='alternate'
links (particularly to those generated by my proposed code review in #7271).
For SEF URL there was no problem, but for non-SEF URL there were some issues with home pages links.
Current implementation generates URLs of this kind (assuming the default "Featured Articles" home page): http://example.com/index.php?option=com_content&view=featured&Itemid=102&lang=en
The proposed code, instead, generates URLs of this kind (independently of the referenced menu type): http://example.com/index.php?lang=en
. This kind of links is more than enough for menu items flagged as an "Home page".
rel='alternate'
links generated by the Language Filter.Much of the code in the Language Switcher helper class and in the onAfterDispatch() method of the Language Switcher is common and has the function to generate "associated" links between different languages.
I think it would be a good idea to introduce a new public method (e.g.: getAssociatedLinks()
) to perform that function, use it in both cases and have it publicly available. This should probably go in the JLanguageHelper class...
That method will need a switch (true/false) to choose if a link to the corresponding home page should be generated in case no association is found.
Status | New | ⇒ | Pending |
Labels |
Added:
?
|
Category | ⇒ | Multilanguage |
Can somebody please restart the Travis job? Thanks!
@Hackwar Hannes, sorry to bring you in but I have a problem that I cannot understand if it is due to me doing something wrong or the 3rd party component which I'm testing (Ohanah) that is in error:
In order to decide if I should look for menu items associations I compare the current link:
$current_link = JUri::getInstance()->toString(array('path', 'query'));
with the active link:
$app = JFactory::getApplication();
$menu = $app->getMenu();
$active = $menu->getActive();
$active_link = JRoute::_($active->link . '&Itemid=' . $active->id, false);
Only if the two are identical I assume being on a "true menu item" and I seek item association for it (if not it could be something related, like e.g. a search result page, but not the "true" menu item).
Now, for a particular 3rd party component (Ohana, an "events manager") I have a menu item whose alias is /en/calendar
and its link is index.php?option=com_ohanah&view=events&layout=calendar
When I go to that page I have $current_link = /en/calendar
(of course) but for $active_link what I get from JRoute is /en/calendar?view=events&layout=calendar
.
The two differs and association is not seeked.
Now of the two:
Many-many thanks in advance for any help you could provide!
P.S.: I'm addressing this to @Hackwar as our "resident routing authority", but of course anyone who could shed some light on this is warmheartedly welcome!
I just verified that current language switcher implementation does not make the check I'm doing.
If you have two associated Search menu items, aliases = search
, links = index.php?option=com_search&view=search
, when you perform a search and get redirected to the results page (which has a link of the kind /it/search-4?searchword=fubar&ordering=newest&searchphrase=all
), the language switcher maintains association to the original associated menu item (the "naked" /search
).
I can accomplish this in two ways:
$current_link = JUri::getInstance()->toString(array('path'));
I have the feeling that the latter should always give the same results as JRoute::_($active->link . '&Itemid=' . $active->id, false);
and hence make the test redundant anyway.
Am a I right?
No! the second option will not work for non-SEF URLs: I just have to get rid of that test which is correct in the language filter for generating rel="alternate"
links, but has no land here...
... but I'm anyway convinced that Ohanah router is wrong!
Without having the time to look into this more deeply: Please don't check on $mode_sef. The code should never make a difference for the configuration of the router.
And I would say that most likely the router of the component is the culprit.
@Hackwar Thanks for answering, Hannes!
... Please don't check on $mode_sef. The code should never make a difference for the configuration of the router.
The only case where I check on $mode_sef is for building the home pages URLs as I want them to be normalized to one of two forms:
'/' . $language->sef . '/';
'/index.php?lang=' . $language->sef
This is important for non-SEF mode where we can have several equivalent alternatives (also referencing the component and view), but where I think it is better to use the neutral forms.
And I would say that most likely the router of the component is the culprit.
Probably yes, but I would say that there was a (now fixed) contributory negligence on my side.
OK, someone break this down for me. What actions in this code make a specific check for whether the user is at the "true" homepage versus on a page using the default menu item configuration warranted? Also, what bug have you reached that requires you to parse the URL based on the SEF mode configuration? Between JRoute and JUri, this should not be a required behavior and if it is that tells me you have found a bug and elected to work around it instead of address it.
What actions in this code make a specific check for whether the user is at the "true" homepage versus on a page using the default menu item configuration warranted?
The true home pages must be handled differently, both in the "Language Switcher" and in the "Language Filter" (for rel=alternate
links), as in both cases we definitely want an association between them independently from the fact that an explicit one (by menu item or by component) is defined (different languages could even use different components for their home pages...).
Beside that, with this PR (as already stated several times in different places) we have a normalization of the true home pages to something like http://example.com/en/
or http://example.com/index.php?lang=en
. This, of course, is good for SEO reasons.
Also, what bug have you reached that requires you to parse the URL based on the SEF mode configuration?
As stated in this PR description, this doesn't fix any bug: it is just a "code review" whose primary objective is:
... stricter adherence of the generated links to those generated by the Language Filter for
rel='alternate'
links (particularly to those generated by my proposed code review in #7271).
This, again, is done mainly for SEO reasons (minimize duplicate links of different form by using the more canonical form possible)
And, as stated in the description, I foresee the possibility to unify much of the logic of the Language Switcher and the creation of rel=alternate
links in the Language Filter in a single method. But this can be left for a second phase...
I have to gladly admit that both Michael and Hannes were absolutely right!
There is no need to explicitly test for the true home page (it falls into the default case) and no need to differentiate between SEF and non-SEF (thanks to JRoute()) and thus the code has been further and greatly simplified!
MANY thanks to both!
... but wait: I'm seeing something wrong... will report...
Hannes we have a problem with latest code:
Visit one of the associated categories:
@Hackwar I think this is the best I can do...
If you think there is something wrong with it and can be simplified, please try it before... I did, and it didn't worked for me.
I don't know if this is because of something unexpected in the router, but I really tried, with all possible cases, and only this code does work correctly.
I'd really love to be proved wrong, sincerely!
To further elaborate, we can avoid the SEF/non-SEF stuff and just have:
// No association found, link to home page
default:
$language->link = JRoute::_('index.php?Itemid=' . $home_pages[$language->lang_code]->id . '&lang=' . $language->sef);
But then we will have links of this kind for the home pages:
/index.php?option=com_content&view=article&id=6:article-2-fr-fr&catid=15&lang=fr&Itemid=104
Which is exactly what I don't want to have!
Status | Pending | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2015-07-13 08:08:53 |
Closed_By | ⇒ | smz |
Status | Closed | ⇒ | New |
Closed_Date | 2015-07-13 08:08:53 | ⇒ | |
Closed_By | smz | ⇒ |
Status | New | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2015-07-13 10:23:53 |
Closed_By | ⇒ | smz |
Travis needs a kick in the butt for PHP:5.4