Accessing Content Policies from AEM Dialogs and Components
Editable Templates have introduced some pretty powerful functionality into AEM including:
- Granting Authors the ability to create page templates using the AEM Authoring Interface, without needing the help of a developer
- Reducing the number of Page components that need to be created and maintained in HTL/JSP
- Modernization of component “designs”, now known as Content Policies, that define the global configuration for a page or component
A Senior User Experience (UX) engineer at my company was exploring ways to make sites more configurable without having to get under the hood and into the code.
We thought it would be cool to allow Template Authors to define a set of global settings that applied across all pages; things like fonts, colors, and logos.
We wanted to take it a step further, and allow Template Authors to set the default values for various components, as well as define which options were available in component dialogs during Authoring.
Content Policiy Configuration Dialogs, the modern replacement for AEM Component Design Dialogs 1, seemed like an appropriate place to allow Template Authors to define global settings, as well component defaults and available Authoring options.
The trick would be accessing the Content Policy from within the components themselves, and pulling out the user-defined values
Ways to Resolve the ContentPolicy Object
After some research, I found that resolving a Page or Content Policy was pretty easy with the help of the ContentPolicyManager object. Once I had a handle on the ContentPolicy object, the .getProperties() function would return a ValueMap that I could easily work with.
import org.apache.sling.api.resource.ResourceResolver; import com.day.cq.wcm.api.policies.ContentPolicy; import com.day.cq.wcm.api.policies.ContentPolicyManager; import org.apache.sling.api.resource.ValueMap; // placed within Sling Model or Java-Use API ResourceResolver resourceResolver = resource.getResourceResolver(); ContentPolicyManager policyManager = resourceResolver.adaptTo(ContentPolicyManager.class); ContentPolicy contentPolicy = policyManager.getPolicy(resource); ValueMap policyValues = contentPolicy.getProperties();
I also realized that a Resource could be adapted directly to a ContentPolicy:
import com.day.cq.wcm.api.policies.ContentPolicy; // placed within Sling Model or Java-Use API // resolve policy directly from resource ContentPolicy contentPolicy = resource.adaptTo(ContentPolicy.class); // resolve from known Page or Content Policy Path String policyNodePath = "/conf/mysite/settings/wcm/policies/mysite/components/pages/page/policy_1579647945834"; Resource policyResource = resource.getResourceResolver().getResource(policyNodePath); ContentPolicy policy = policyResource.adaptTo(ContentPolicy.class);
Accessing the ContentPolicy Object from within an AEM Dialog / Granite UI Field
The next step in our vision was to modify Page Properties and Component Authoring dialogs to contain the default values and available options specified by the Template Authors in their Content Policies.
While this idea was never fully fleshed out (e.g. how would values be resolved inside of a Component’s Sling Model? There would need to be a way to check the ContentPolicy for defaults if no value was defined on the content node), I did discover an interesting way to resolve the ContentPolicy from within a Granite UI Form Field. The trick was to find the page path first, and use that to resolve the ContentPolicy object.
After several tries, I found a method described here to pull the page path out of the request object using the Value.CONTENTPATH_ATTRIBUTE attribute.
// placed within a Granite UI Form Field JSP (e.g. TextField's render.jsp) String currentPagePath = (String)request.getAttribute(Value.CONTENTPATH_ATTRIBUTE); Resource currentResource = resource.getResourceResolver().getResource(currentPagePath); ContentPolicyManager cpm = resource.getResourceResolver().adaptTo(ContentPolicyManager.class); ValueMap contentPolicyProps = cpm.getPolicy(currentResource).getProperties();
Once I has the ContentPolicy properties ValueMap, I was free the output the configured default value straight into the Form Field.
Context-Aware Configuration Gotchas
I had some difficulty relating to how our Context-Aware Configuration was set up. I was able to alleviate the issue by making sure the cq:conf property on my /content tree pointed to a location that contained the WCM Editable Templates and Content Policies (originally it was only pointing to my SiteConfig node).
No responses yet