adobe / aem-core-wcm-components

Standardized components to build websites with AEM.
https://docs.adobe.com/content/help/en/experience-manager-core-components/using/introduction.html
Apache License 2.0
723 stars 737 forks source link

Alternative Language Links Missing when Language Nav is templated from structure #2756

Open HitmanInWis opened 1 month ago

HitmanInWis commented 1 month ago

Version: 2.24.7-SNAPSHOT

Bug Report

If the language nav on the page is within the Structure portion of an Experience Fragment, it is not detected, and thus the Alternative Language links are missing from the page .

The bug is in LanguageNavigationSiteRootSelectionStrategy::findFirst - in searching for a Language Nav component, it correctly finds Experience Fragment References and searches the linked Experience Fragments for Language Nav, but if the XF itself does not have the Language Nav node (because it is coming from a template structure) then the code wont find it.

The solution is simple - update the following code

            return Optional.ofNullable(resource.adaptTo(ExperienceFragmentDataImpl.class))
                .map(ExperienceFragmentDataImpl::getLocalizedFragmentVariationPath)
                .map(xfPath -> resource.getResourceResolver().getResource(xfPath))
                .flatMap(xfResource -> findFirst(xfResource, condition, containingPage));

to

            return Optional.ofNullable(resource.adaptTo(ExperienceFragmentDataImpl.class))
                .map(ExperienceFragmentDataImpl::getLocalizedFragmentVariationPath)
                .map(xfPath -> resource.getResourceResolver().getResource(xfPath))
                .map(xfResource -> ComponentUtils.getEffectiveResource(xfResource, null))  // this is new code
                .flatMap(xfResource -> findFirst(xfResource, condition, containingPage));

As a side note, LanguageNavigationSiteRootSelectionStrategy#findLanguageNavigation(org.apache.sling.api.resource.Resource, com.day.cq.wcm.api.Page) should also be refactored to use ComponentUtils.getEffectiveResource(contentResource, null)