adobe / adobe/aem-core-wcm-components
[Navigation] Incorrect behavior if navigation root belongs to a different site
- Dominant language
- Java
- Stars
- 795
- Forks
- 775
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 8
Description
## Bug Report
**Current Behavior**
When using the Navigation component, if the specified Navigation Root belongs to a language root that is not a sibling of the current pages language root, the current pages language root is used as the navigation root anyway.
Consider the following structure
- content
- site-A
- en
- home
- site-B
- en
- home
If the page (or subpage) of `/content/site-B/en/home` uses content in Site-A as the navigation root, then the Navigation model determines that the current page has the language root of `/content/site-B/en`, and the specified navigation root has the language root of `/content/site-A/en`, it concludes that these are not the same, and therefore must be language copies. The effective navigation root that is used to build the navigation is `/content/site-B/en/home`.
In reality, these two sites are not related, they are not sibling languages, if the intent is to show the navigation of Site-A on Site-B, it is not acceptable to show the navigation of Site-B.
**Expected behavior/code**
If the language root for the current page differs from the language root of the navigation root - as specified in the component properties - they should then be tested to determine if they are sibling languages.
**Environment**
- AEM version and patch level: AEM-6.4.6.0
- Core Components version: 2.7.0
- JRE version : 1.8.0
**Possible Solution**
There are a couple possible solutions.
The following snippet can determine if two language roots are siblings:
```java
languageManager.getAdjacentLanguageInfo(resourceResolver, currentPageLanguageRoot.getPath())
.values().stream()
.map(LanguageManager.Info::getPath)
.anyMatch(path -> path.equals(navigationRootLanguageRoot.getPath()))
```
The above snippet can be used [here (line 119 of the navigation model implementation)](https://github.com/adobe/aem-core-wcm-components/blob/90a672a0b01b74ebb263bfbe233af7d4aa1dd5ca/bundles/core/src/main/java/com/adobe/cq/wcm/core/components/internal/models/v1/NavigationImpl.java#L119).
It may be satisfactory to just compare that if the two language roots differ, that they have a common parent. I am not familiar enough with multi-lingual sites to be able to determine if that is true.
A more advanced solution may, if it is determined that the two language roots differ and are not siblings, then check if they are for the same language, and if not then try to fetch the correct language root from the correct site.
For example, if we have the following sites
/content/site-A/en/home
/content/site-A/fr/home
/content/site-B/en/home
/content/site-B/fr/home
if the `/content/site-B/fr/home` references `/content/site-A/en/home` in a navigation component, it may elect to use `/content/site-A/fr/home` instead, so that it is selecting the correct language from the correct site, as opposed to selecting the correct language from *this* site.
All the information necessary to determine those paths is available from the language manager.
I am willing to submit a PR if the issue is accepted and a solution is chosen.
Contributor guide
Research direction
Start in bundles/core/src/main/java/com/adobe/cq/wcm/core/components/internal/models/v1/NavigationImpl.java at the referenced language-root logic. Read how the LanguageManager determines adjacent language roots and compare that behavior with the cross-site structure described in the report. Done means a navigation root from another site is not replaced by the current page's root, with the intended multilingual behavior covered by relevant Navigation tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend, web-dev
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100