Requirement: To create a custom navigation component, those component root should be based on specific template, first match the template and fetch the pages under that template and shows in the page when created navigation component drag and drop at page. Simply the dynamic way to call templates and its template selected pages should display at customized navigation component.
Note: Not in the authoring, solution required code based.
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
Creating a custom navigation component in AEM that dynamically fetches and displays pages based on a specific template is feasible. Here’s a high-level overview of how you can achieve this:
Steps to Create Custom Navigation Component
1. Component Definition:
2. Sling Model:
3. JCR Query:
4. HTL Script:
Example Implementation
1. Component Definition
Create the component under `/apps/myproject/components/custom-navigation` and add a dialog to allow template selection.
dialog.xml:
<jcr:root
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Custom Navigation"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<tabs jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs">
<items jcr:primaryType="nt:unstructured">
<tab1
jcr:primaryType="nt:unstructured"
jcr:title="Properties"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<templatePath
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldLabel="Template Path"
name="./templatePath"
rootPath="/apps/myproject/templates"/>
</items>
</tab1>
</items>
</tabs>
</items>
</content>
</jcr:root>
2. Sling Model
Create a Sling Model to fetch the pages.
NavigationModel.java:
package com.myproject.core.models;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.PageManagerFactory;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.api.resource.QueryBuilder;
import org.apache.sling.api.resource.Query;
import org.apache.sling.api.resource.query.QueryBuilderException;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class NavigationModel {
@inject
private ResourceResolver resourceResolver;
@inject
private QueryBuilder queryBuilder;
@ValueMapValue
private String templatePath;
public List<Page> getPages() {
List<Page> pages = new ArrayList<>();
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
try {
Query query = queryBuilder.createQuery("SELECT * FROM [cq:Page] AS s WHERE ISDESCENDANTNODE([/content]) AND [jcr:content/cq:template] = '" + templatePath + "'", resourceResolver);
query.getResult().getNodes().forEachRemaining(node -> {
Page page = pageManager.getContainingPage(node);
if (page != null) {
pages.add(page);
}
});
} catch (QueryBuilderException e) {
// Handle exception
}
return pages;
}
}
3. HTL Script
Create an HTL script to render the navigation.
custom-navigation.html:
<sly data-sly-use.navigationModel="com.myproject.core.models.NavigationModel">
<ul>
<sly data-sly-list.page="${navigationModel.pages}">
<li>
<a href="${page.path}">${page.title}</a>
</li>
</sly>
</ul>
</sly>
Feasibility and Considerations
1. Performance: Ensure the query is optimized to avoid performance issues, especially if there are many pages.
2. Security: Validate the user input for the template path to avoid injection attacks.
3. Caching: Implement caching mechanisms to reduce the load on the repository for frequently accessed navigation components.
4. Error Handling: Handle errors gracefully to ensure a robust implementation.
By following these steps, you can create a custom navigation component in AEM that dynamically displays pages based on a selected template.
Creating a custom navigation component in AEM that dynamically fetches and displays pages based on a specific template is feasible. Here’s a high-level overview of how you can achieve this:
Steps to Create Custom Navigation Component
1. Component Definition:
2. Sling Model:
3. JCR Query:
4. HTL Script:
Example Implementation
1. Component Definition
Create the component under `/apps/myproject/components/custom-navigation` and add a dialog to allow template selection.
dialog.xml:
<jcr:root
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Custom Navigation"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<tabs jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs">
<items jcr:primaryType="nt:unstructured">
<tab1
jcr:primaryType="nt:unstructured"
jcr:title="Properties"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<templatePath
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldLabel="Template Path"
name="./templatePath"
rootPath="/apps/myproject/templates"/>
</items>
</tab1>
</items>
</tabs>
</items>
</content>
</jcr:root>
2. Sling Model
Create a Sling Model to fetch the pages.
NavigationModel.java:
package com.myproject.core.models;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.PageManagerFactory;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.api.resource.QueryBuilder;
import org.apache.sling.api.resource.Query;
import org.apache.sling.api.resource.query.QueryBuilderException;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class NavigationModel {
@inject
private ResourceResolver resourceResolver;
@inject
private QueryBuilder queryBuilder;
@ValueMapValue
private String templatePath;
public List<Page> getPages() {
List<Page> pages = new ArrayList<>();
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
try {
Query query = queryBuilder.createQuery("SELECT * FROM [cq:Page] AS s WHERE ISDESCENDANTNODE([/content]) AND [jcr:content/cq:template] = '" + templatePath + "'", resourceResolver);
query.getResult().getNodes().forEachRemaining(node -> {
Page page = pageManager.getContainingPage(node);
if (page != null) {
pages.add(page);
}
});
} catch (QueryBuilderException e) {
// Handle exception
}
return pages;
}
}
3. HTL Script
Create an HTL script to render the navigation.
custom-navigation.html:
<sly data-sly-use.navigationModel="com.myproject.core.models.NavigationModel">
<ul>
<sly data-sly-list.page="${navigationModel.pages}">
<li>
<a href="${page.path}">${page.title}</a>
</li>
</sly>
</ul>
</sly>
Feasibility and Considerations
1. Performance: Ensure the query is optimized to avoid performance issues, especially if there are many pages.
2. Security: Validate the user input for the template path to avoid injection attacks.
3. Caching: Implement caching mechanisms to reduce the load on the repository for frequently accessed navigation components.
4. Error Handling: Handle errors gracefully to ensure a robust implementation.
By following these steps, you can create a custom navigation component in AEM that dynamically displays pages based on a selected template.
Potential Problems and Challenges
Note: You can directly use navigation component, and then author those component
Authoring process is making in few steps, but coding and its process it will takes more complexity. Not recommended direct use navigation component.
Hi @RajeevMa ,
To create a custom navigation component in AEM that fetches pages based on a specific template, you can follow these steps:
1. Create a new component: Create a new component for your custom navigation. This component will be responsible for fetching and rendering the pages based on the specific template.
2. Define the component properties: Define the necessary properties for your custom navigation component. This may include properties to specify the template to filter pages, the number of levels to display, and any other customization options.
3. Implement the component logic: In the component's logic, you will need to fetch the pages based on the specified template. You can use the AEM QueryBuilder API or the JCR API to query for pages that match the template.
4. Render the navigation: Once you have fetched the pages, you can render the navigation using the appropriate HTML markup and CSS styling. You can use a loop to iterate over the fetched pages and generate the navigation structure.
5. Add the component to a template: To make the custom navigation component available for use, you need to add it to a template. Edit the template that you want to associate with the custom navigation component and include the component in the appropriate location.
6. Configure the component properties: When adding the custom navigation component to a page, you can configure the properties to specify the template and any other customization options.
By following these steps, you can create a custom navigation component in AEM that fetches pages based on a specific template and displays them dynamically.
Views
Replies
Total Likes
@RajeevMa Did you find the suggestions from users helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.
Views
Replies
Total Likes
Views
Likes
Replies