? Pending

User tests: Successful: Unsuccessful:

avatar Giuse69
Giuse69
11 Nov 2018

Pull Request for Issue #22656 .

Summary of Changes

This PR extends mod_language to publish correct language flag links when an article that has language set to all (*) is being viewed (view=article) and current menu item has associations for other languages.
Currently since an any-language article cannot have associations but it is actually valid for being viewed in all installed languages, language switcher currently presents flag links pointing only to associated menu items but not to current article under associated menus in other languages.
The proposed solution is compatible with 3rd party components that override com_content so for building the routes with JRoute, the component of active menu is used and not the component of current URL, since with 3rd party components they can be different: the active menu component is of the 3rd party component while current URI component is always com_content.
Feel free to suggest improvements to code but keeping this compatibility with third party components.

Testing Instructions

Backend Setup Scenario:

  • a multilingual site with at least 2 installed content languages LANGA and LANGB
  • a category CAT with language = All.
  • an article ART with language = All, id = ARTID, alias = ARTALIAS
  • a menu item for language LANGA of type "list article of category CAT", alias = MENUA
  • a menu item for language LANGB of type "list article of category CAT", alias = MENUB
  • language switcher module published
  • SEF enabled (similar test for SEF disabled).

FrontEnd:

  • while browsing in language LANGA, go to article view of ART: current URL will be .../MENUA/ARTID-ARTALIAS.
    Now look at flag link for LANGB in the language switcher.

Expected result

  • link for LINGB should be .../MENUB/ARTID-ALIAS

Actual result

  • link for LINGB is .../MENUB

Documentation Changes Required

For Developers, as said in the exec summary, this change works also with third party components overriding com_content: you have a menu link URL like "option=com_XXX&task=search..." that presents a list of articles, then clicking on an article you are directed to a view=article page with URL like "option=com_content&view=article..." - here this PR will deal with building correct language associations for any-language articles using com_XXX and not com_content.
This PR can be extended to language filter plugin to set metadata hreflang in for any-language article.

avatar Giuse69 Giuse69 - open - 11 Nov 2018
avatar Giuse69 Giuse69 - change - 11 Nov 2018
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 11 Nov 2018
Category Modules Front End
avatar Giuse69 Giuse69 - change - 11 Nov 2018
Labels Added: ?
avatar Giuse69 Giuse69 - change - 11 Nov 2018
The description was changed
avatar Giuse69 Giuse69 - edited - 11 Nov 2018
avatar SharkyKZ
SharkyKZ - comment - 11 Nov 2018

There should be no component-specific code in the module.

avatar Giuse69
Giuse69 - comment - 11 Nov 2018

yes, it is like that, no reference to any specific component, you can check the code

avatar mbabker
mbabker - comment - 11 Nov 2018

if ($input->get('option') == "com_content" && $input->get('view') == "article")

You have added a code path specifically for when the request is to the article view of com_content. Meaning you have component and view specific code in the module.

avatar Giuse69
Giuse69 - comment - 12 Nov 2018

Ok, sorry, I thought you meant code specific to non-Joomla components. I removed that reference to "com_content" so now it should be as you say, correct?

avatar Giuse69
Giuse69 - comment - 12 Nov 2018

I don't understand the drone and travis "build failed" after just changing one line: drone failed for an error in jquery (not here) and travis for missing PHP 7.3 compatibility..? Sorry I am a newbie for these checks... thanks a lot for your help

avatar SharkyKZ
SharkyKZ - comment - 12 Nov 2018

There's still component-specific code in here. Article view is specific to com_content. You are loading a record from Content table. ID and alias fields may not exist in other components.

That said, this probably needs to be implemented in association helpers for each component.

avatar Giuse69
Giuse69 - comment - 12 Nov 2018

The case that is being handled by this PR is for article view, so if there is an article view, an article should exist.
An alternative approach (as said in the issue) would be association helpers to return an association when there is not but the item has language = "*", would it be better?

avatar infograf768
infograf768 - comment - 13 Nov 2018

The possible solution can't be anywhere else than in the associations helpers and this would require a lot of tests to be sure it does not break anything else and be B/C.

avatar Giuse69
Giuse69 - comment - 18 Nov 2018

Ok, this PR is aimed at enhancing management of any-language articles with compatibility with 3rd party components that use and override com_content, so that you can define a menu item for a component com_XXX that shows a list of articles and, clicking on one of them, you get an article view. In this case current URL has option=com_content but active menu has option=com_XXX and I'd like to make a PR where Joomla uses com_XXX and not com_content. Without any 3rd party components -a native Joomla-only environment- both current URL and active menu have com_content so everything would work and B/C is then preserved.
I then studied an alternative solution since you say that this modification of mod_languages is not the good way to go and here I ask for advice: currently mod_languages (1) helper calls
call_user_func(array("ContentHelperAssociation", 'getAssociations'))
since it uses the component from URL. This method (2) retrieves association calling JLanguageAssociations (that queries the DB) and finally calls
ContentHelperRoute::getArticleRoute(art_id, cat_id, lang)
Now, all these steps uses com_content router, in no point com_XXX component Router is invoked and that's the problem.
So the question is: where is the right place to use active_menu (com_XXX) component? Two options come to my mind:

  1. in mod_languages helper, calling getAssociations of XXXHelperAssocations and not ContentHelperAssociations, but I think it's wrong since a third party component does not have to define its own HelperAssociations, am I right?
  2. in com_content\helpers\associations: after calling getAssociations of src\Language\Associations.php, invoke routing based on active menu component instead of invoking getArticleRoute.

So I have to go with option2? Or another one?
thanks

avatar infograf768
infograf768 - comment - 19 Nov 2018

Now, all these steps uses com_content router, in no point com_XXX component Router is invoked and that's the problem.

Not sure what you mean. For me the helper is calling each component with the right class, if it exists:

			// Load component associations
			$option = $app->input->get('option');
			$class = ucfirst(str_replace('com_', '', $option)) . 'HelperAssociation';
			\JLoader::register($class, JPATH_SITE . '/components/' . $option . '/helpers/association.php');

			if (class_exists($class) && is_callable(array($class, 'getAssociations')))
			{
				$cassociations = call_user_func(array($class, 'getAssociations'));
			}
		}

Examples:
ContentHelperAssociation calls ContentHelperRoute::getArticleRoute
ContactHelperAssociation calls ContactHelperRoute::getContactRoute
NewsfeedsHelperAssociation calls NewsfeedsHelperRoute::getNewsfeedRoute
and same for weblinks.

For Categories it correctly fetches the getCategoryRoute from the RouteHelper.

Each multilingual aware component REQUIRES a specific HelperAssociation in frontend and an AssociationsHelper in backend.

avatar Giuse69
Giuse69 - comment - 19 Nov 2018

Thanks, but the point is which is "the right class"? My question is where the component of current URL is different from the component of active menu item. For example when a SEF URL is requested, the parse process uses the component router of found menu item, while mod language uses current URL component router and not active menu component router.
This distinction is invariant for a Joomla only site but makes a difference when there is a third party override/extension of com_content.
Is this more clear? If not, I can try again to explain.

avatar Giuse69
Giuse69 - comment - 19 Nov 2018

In other words, to pick up the component, you can either take it from input or from active menu. And they can be different if a third party component is present.

avatar infograf768
infograf768 - comment - 19 Nov 2018

Component items associations comes first. the class is unique and found with the code above. It has priority.
if no component associations, then comes the menu item associations. In this case, one can associate any type of menu item to another, even if it does not concern the same component.

avatar Giuse69
Giuse69 - comment - 21 Nov 2018

Yes, what I was considering is the following scenario:

  • a list of articles shown in a page of a third party component com_XXX with Itemid=
  • the user clicks on the title/link of one the articles of the list and is directed to a...
  • page with view=article, let's call it ART_PAGE, where url has option=com_content since XXX overrides com_content.
    Now, to retrieve which are the pages associated to ART_PAGE in other languages, it is necessary to invoke JRoute passing com_XXX and not com_content, so I was thinking of this sequence:
  1. retrieving the component from input, let's call it C1, and use it for retrieving associated items (i.e. associated articles) - AS NOW
  2. retrieve active menu and its component C2 - AS NOW
  3. if found associated items in step 1, call JRoute BUT replacing C1 with C2 in the passed URL.
    Does it make sense?
    thanks
avatar Bakual
Bakual - comment - 22 Nov 2018

Umm, I think trying to cope for components that do override other components is actually bad. That com_XXX (if that exists) does something which is unsupported in Joomla and probably already needs several nasty workarounds to get it working. Leave that to the component designer, it's not our problem.
We retrieve the active component from JInput everywhwere in core.

avatar Giuse69
Giuse69 - comment - 25 Nov 2018

Yes, it does exist :). I understand that such components that have a different component from active menu link to current URL are not what a clean Joomla expects, so I am closing this PR.
Thanks for all the suggestions.

avatar Giuse69 Giuse69 - change - 25 Nov 2018
Status Pending Closed
Closed_Date 0000-00-00 00:00:00 2018-11-25 17:06:16
Closed_By Giuse69
avatar Giuse69 Giuse69 - close - 25 Nov 2018

Add a Comment

Login with GitHub to post a comment