AEM provides a great WYSIWYG interface to drag and drop a discrete set of components onto a page. This interface, however, does not account for components that need to be added to a page dynamically. This post will discuss how to add sets of components to a page programatically based on custom logic.
A previous post discussed strategies for componentizing AEM content, and featured a new “bestsellers” component for the Geometrixx demo site. Here, that example will be used and built upon. To follow along, first install the completed package from the last walkthrough.
Step 1: Create a set of “bestseller” component instances in a new page
After installing the package linked above, the Geometrixx products page lists a static set of “best sellers” that are dragged onto the page as whole, discrete components. The goal for this example is to have the bestseller components loaded into this page dynamically, as opposed to being permanently stored there. So we will need to create another “permanent home” page for all best seller components to be defined, stored, and modified.
Create a new page using AEM’s Site Builder. Because this page is not going to be directly viewed by end users, details like name and location won’t matter. For this demo, a page is created in this location:
Create this page, open it, and add 5-10 bestseller component instances that have been customized to display various shapes. This page may require edits to the design dialog of its par. Also, depending on the page type and template used, formatting might be gone. This is perfectly fine, because this page is only used as a location for authors to create and customize instances of bestsellers for the purpose of loading them elsewhere.
While creating and modifying these bestsellers, it may be easier start by copying and pasting nodes from within CRXDE in the /content folder location after the first few are created.
Step 2: Create a “loader” component to fetch content “content” components
Following the same pattern as the bestseller component, create a new component called “bestsellerloader”. This new component will have the responsibility of fetching existing instances of bestseller components from a node in the content repository, then displaying them on the currently-viewed page. In a real application, bestsellerloader would contain configuration configuration options such as the maximum number of items to display, or the location of “storage” node where those items are located. These options would be controlled by design and edit dialogs. This example hardcodes everything for convenience.
With a hardcoded link to the node in which the bestseller components are stored, a resourceResolver object, already instantiated and available, can be used to return the list of nodes. Looping through these, a <sling:include> tag can be used to inject them directly into the page. Note that the sling:include tag is processed during page rendering, and users will only see the final result. Other options for loading components after page load will be demonstrated in future posts.
Step 3: Add logic and formatting to bestsellerloader
Add the bestsellerloader component to the Geometrixx Products Page, in place of the original, individually added components. When viewing the page, the bestseller components will now be loading dynamically from the bestsellerloader component. One thing that is lost from the originally page, however, is the two-column row formatting. Fortunately we can inject that formatting back into bestsellerloader.
The above approach should be considered a “quick and dirty” solution, as we’re not directly utilizing AEM’s built-in column controls, nor are we making the bestsellerloader very flexible for reuse on other pages that aren’t intended for 2-column formatting. While much of that can be cleaned up, it does illustrate the point that control over how the component instance’s HTML is laid out has been taken away from the page, and given to the loader. Sometimes the limitation of this necessitates the creation of multiple loader components to fit the needs and logic of particular pages.
Summary: While the previous post demonstrated how to create individual components for direct inclusion on a page, this demo shows how to indirectly load component sets from location. This was accomplished by creating an author-only “storage” page, where new instances of components were to be created, and a “loader” component, which will pull these instances from storage page to a user-facing page.