Extend Experience fragments of core using delegation pattern | Community
Skip to main content
Level 3
December 19, 2023
Solved

Extend Experience fragments of core using delegation pattern

  • December 19, 2023
  • 2 replies
  • 2459 views

Hello Members,

 

We are trying to extend Core Experience fragment to meet our client needs where each page can have its own header and footer.

The approach we are trying now is to unlock the experience fragment in the structure so that the author can configure per page which works fine.

 

However, on top of this we need same Experience fragment header to be set for all the child pages below . I am using Delegate pattern for the same and unfortunately this seems to not work .

 

Note: We are using aem-react-editable-components so the mapping happens in import-component.js and not the usual way with html. 

 

 

Below is my Implementation

 

@Model(adaptables = { Resource.class, SlingHttpServletRequest.class }, adapters = { ExperienceFragment.class }, resourceType = CustomExperienceFragmentImpl.RESOURCE_TYPE, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) @Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) @Getter public class CustomExperienceFragmentImpl implements ExperienceFragment { protected static final String RESOURCE_TYPE = "myproject/components/core/experiencefragment"; @Self @Getter(AccessLevel.NONE) private SlingHttpServletRequest request; private String fragmentVariationPath; @PostConstruct void init() { InheritanceValueMap properties = new HierarchyNodeInheritanceValueMap(request.getResource()); fragmentVariationPath = properties.getInherited(ExperienceFragment.PN_FRAGMENT_VARIATION_PATH, String.class); } @Self // Indicates that we are resolving the current resource @Getter(AccessLevel.NONE) @Via(type = ResourceSuperType.class) // Resolve not as this model, but as the model of our supertype (ie: CC Image) @Delegate(excludes = DelegationExclusion.class) // Delegate all our methods to the CC Image except those defined below private ExperienceFragment delegate; @Override public String getLocalizedFragmentVariationPath() { return fragmentVariationPath!=null ? fragmentVariationPath : delegate.getLocalizedFragmentVariationPath(); } private interface DelegationExclusion { String getLocalizedFragmentVariationPath(); // Override the method which determines the source of the asset } }

 

Kindly share your views

 

Thanks

Arun

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by Jeevan-Eranti

Hi @user70744 

 

Please refer to the article below for instructions on configuring dynamic headers and footers. Additionally, explore extending the Experience Fragment model to support localized headers/footers with a custom site structure using the delegation pattern.

https://www.albinsblog.com/2021/10/extend-aem-experience-fragment-localization.html

 

2 replies

Jeevan-ErantiAccepted solution
Level 2
December 19, 2023

Hi @user70744 

 

Please refer to the article below for instructions on configuring dynamic headers and footers. Additionally, explore extending the Experience Fragment model to support localized headers/footers with a custom site structure using the delegation pattern.

https://www.albinsblog.com/2021/10/extend-aem-experience-fragment-localization.html

 

user70744Author
Level 3
December 19, 2023

hi @jeevan-eranti yes this is the same approach i have implemented unfortunately the delegation does not seem to work for me.

 

The same code is attached as well

 

Thanks

Arun

user70744Author
Level 3
December 21, 2023

Thanks @jeevan-eranti  for explanations. and Indeed i understood and

it works for me with the one we set at page root level. However the items are i get are from the master which is set in template i.e from the path fragmentVariationPath. and hence i am confused. I expected that the Experience fragment delegate will take the configured path at the page root level and render the items from this fragment but seems not..

 

Also i have just copied your sample code and adjusted to our project

 

:items: { experiencefragment-header: { localizedFragmentVariationPath: "/content/experience-fragments/mysite/vu/en/site/sample/master", ---> this is the overridden path from root page :items: { ---> All the items i get here are from the path configured in template due to the Core component }

 

 

Hence i am curious what i miss and which works for you 🙂

 

Thanks

Arun


hi @jeevan-eranti,

 

After few hours of debugging, i could find the issue. I played your same code on WKND project and below are my findings

 

1. This approach is working fine where we use the experiencefragment.html for rendring but not with react based project which uses model.json

2. I have noticed that the model.json is not updated with the overridden path in WKND as well.

3. Reason for this is the core Experience fragment has a private method to get the children of the path i.e localizedFragmentVariationPath which always gives the path configured in structure as this is derived from ExperienceFragmentDataImpl model which is internal and was not able to extend or override.

 

Hence i had to use a workaround now to set this path using reflection so that the model.json gets updated and react picks the items rendered to show on page

 

Thank you very much for the idea provided earlier.

If you can test the model.json in your project where this is implemented i can be 100% sure that its a problem in Core component then

 

Thanks

Arun

arunpatidar
Community Advisor
Community Advisor
December 19, 2023
user70744Author
Level 3
December 19, 2023

Thanks @arunpatidar but this post uses slightly. however i would need to do in Model so that its available in model.json and react would pick the path