May 2, 2020
Estimated Post Reading Time ~

Fantastic AEM Configurations and How to Code Them

One of the most powerful concepts in Adobe Experience Manager is the separation of configuration spaces. Unfortunately, it is also one of the most misunderstood concepts.
When I first started using Adobe Experience Manager, I knew something about web development, but when it came to the realities of using the software in an enterprise organisation, I knew about as much as Jon Snow knew about life beyond the wall.

In software, a configuration is almost always a double-edged sword. It might be necessary from time to time, but without proper training and handling, you are likely to hurt yourself. As a responsible developer who does not want user complaints all over your issue tracker, you should keep the most dangerous configurations out of reach of your less knowledgeable users, but available in case they are needed.

This is what configuration spaces are for. They allow you to separate what can be configured by whom. When used correctly, they reduce both user frustration (because a configuration went wrong) and support time (because a user could not make a necessary change herself). When used incorrectly, they do the opposite and lead to endless frustration.

Policy = Content Policies
Content policies are configurations that govern the behavior of components across an entire section of an AEM website. In AEM versions prior to 6.3, they were sometimes called designs, but for the purposes of clarity, I will call them content policies through this blog post.

Just like the real rules of the road, content policies govern what authors may do on the website. Unlike the rules of the road, AEM content policies don’t get enforced by traffic cops with radar guns, but by developers with APIs (although both groups have been reported to have a preference for donuts).

Just like the real rules of the road, content policies cannot be changed by ordinary users (changing policy requires politics, after all). Unlike the rules of the road, content policies are set by the owners of the site.

Just like the real rules of the road, content policies apply to specific domains. Unlike the rules of the road, content policies do not apply to countries and road types, but to AEM sites and templates.

Content policies are one of the most under-rated elements that AEM developers can use to help authors create great web experiences.

Great content policies enable great web experiences.

The most basic content policy is the definition of components that are allowed for each template. However, using content policies only for that purpose is selling them awfully short and leaves great potential for user experience on the table.


Get ready to edit your content policies for the We.Retail templates

In order to set up a content policy, a site manager would go into AEM, select Tools, then browse to Templates and tap Edit on the template that the policy should apply to.


Each of the above components that has a settings icon next to it supports content policies. On the template page, you can click the settings icon to create, edit, and set the content policy that applies to this component on the given template.


Because there can be many combinations of components and templates in a given AEM site, AEM makes it easy by allowing you to name, describe, and re-use content policies.

The policy settings (or configuration properties) can be defined by the developer of the component and retrieved just as easily as the edit properties.

<cq:design_dialog jcr:primaryType="nt:unstructured" jcr:title="Embed" sling:resourceType="cq/gui/components/authoring/dialog" jcr:description="Content policy for embedding content">
  <content jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container">
    <items jcr:primaryType="nt:unstructured">
      <tabs jcr:primaryType="nt:unstructured" maximized="true" sling:resourceType="granite/ui/components/coral/foundation/tabs">
        <items jcr:primaryType="nt:unstructured">
          <properties jcr:primaryType="nt:unstructured" jcr:title="Main" margin="true" sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
            <items jcr:primaryType="nt:unstructured">
              <content jcr:primaryType="nt:unstructured" margin="false" sling:resourceType="granite/ui/components/coral/foundation/container">
                <items jcr:primaryType="nt:unstructured">
                  <allowedSites jcr:primaryType="nt:unstructured" fieldDescription="If you set a value here, only pages from the listed sites can be embedded." fieldLabel="Allowed sites" sling:resourceType="granite/ui/components/coral/foundation/form/multifield">
                    <field jcr:primaryType="nt:unstructured" name="./allowedSites" required="true" sling:resourceType="granite/ui/components/coral/foundation/form/textfield"/>
                  </allowedSites>
                </items>
              </content>
            </items>
          </properties>
        </items>
      </tabs>
    </items>
    </content>
</cq:design_dialog>

The main difference between the edit configuration and the content policy configuration is the node name, which should be cq:design_dialog. As mentioned above, the name design is a vestige of earlier, more innocent times.

Getting access to a property that has been defined in a content policy is almost as easy as getting an edit property:

<%@include file="/libs/foundation/global.jsp"%><%
  String[] whitelist = currentStyle.get("allowedSites", new String[0]);
%>

In fact, currentStyle.get() is only two characters longer than properties.get() and supports the same casting support, giving you Strings or String arrays as needed.

So, don’t get confused by design or style, and think of defining the rules of the road when creating content policies. And before long, content policies will be your (and your users) favorite tool.

Before long, content policies will be your favorite feature in AEM.Configuration Spaces in Real Life
One way to think about configuration spaces is to think about constraints. Imagine you are driving your car down the highway. Your speed is governed by personal, policy, and physical constraints.
  • Personal constraints: you will not go faster than you want to, because you ultimately control the speed of your car. If you want to change this constraint, it is entirely up to your need for speed (or not).
  • Policy constraints: you may not go faster than the rules of the road which govern maximum allowed speed. If you want to change this constraint, you need to either request a change of policy (ask your government representative to change the speed limit) or change the realm that the policy applies to (there are different speed limits on a county road, an interstate highway, and the Autobahn).
  • Physical constraints: you cannot go faster than your car’s maximum speed, because the engine’s output, combined with wind drag and tire friction, are physical limits. If you want to change this constraint, you need to get a faster car or go to a planet that has lover gravity (although I hear the roads are in pretty bad shape on Mars).
In AEM, there are similar personal, policy, and physical constraints, each managed by a different person and with a different frequency of change.
Configuration Spaces in Adobe Experience Manager

Personal = Authoring
Personal constraints in AEM translate into editing configurations. Every author in AEM can open the edit dialog of a component (assuming they have permissions) and enter values that will directly affect the content and behavior of the configured component.

Because this is one of the most fundamental ways to interact with AEM, it is also very easy to code, and often leads to an over-use of this configuration space. As a rule of thumb, a component in AEM should have no more than five configuration properties, and the median number of configuration properties across all components in a project should be smaller than three.

Anything more complex than this means that more configuration properties need to be explained, documented, trained, and checked for cross-interaction. With just five checkboxes in a component, you can end up with more than thirty combinations that need to be understood, tested, explained, and maintained. Save yourself and your authors from the curse of complexity by asking the question: “how often are users going to enter a value here?”.

A simple edit dialog in an AEM component.

So, how do you declare and access an edit configuration? To declare a configuration, you need an edit dialog. In AEM’s touch UI, this is done through the cq:dialog node, which you can define in CRXDE Lite or using vlt.

<cq:dialog jcr:primaryType="nt:unstructured" jcr:title="Embed" sling:resourceType="cq/gui/components/authoring/dialog">
  <content jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
    <items jcr:primaryType="nt:unstructured">
      <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container">
        <items jcr:primaryType="nt:unstructured">
          <url
                jcr:primaryType="nt:unstructured"
                fieldDescription="URL of a page that supports oEmbed auto-discovery (e.g. YouTube)"
                fieldLabel="Web page address"
                name="./webpage"
                sling:resourceType="granite/ui/components/coral/foundation/form/textfield"/>
        </items>
      </column>
    </items>
  </content>
</cq:dialog>

The components of the dialog are defined using Granite UI, i.e. a declarative, resource-based language for user interface definitions.

As easy as it is to define a dialog, it is even easier to retrieve the edit configuration value.

<%@include file="/libs/foundation/global.jsp"%><%
%><%
  String url = properties.get("webpage", String.class);
%>

However, just because something is easy, it does not mean that it’s the right thing to do. Most edit configurations are better served through content policies and kept out of the authors’ hands. If you don’t know what content policies are, keep on reading.

Physical = OSGi Configuration
Just as the real world is made up of atoms and molecules and governed by the laws of physics, the world of AEM is made up of components and bundles and governed by the laws of the OSGi Alliance.

OSGi configurations can be extremely powerful, but as every Spider-Man fan knows, with great power comes great responsibility. Therefore, OSGi configurations are kept out of the hands of ordinary users and should be avoided by most developers.

Think of building an OSGi configuration as building a knob that allows you to alter the laws of physics. com.adobe.cq.components.constants.Newtonian.c allows you to set the speed of light, something you should (almost) never have to do.

If you have questioned what happens when you play with the forces of reality, ask Dr. Stephen Strange or your friendly neighborhood AEM administrator.

If you can see this, you went too far.



















    In many AEM projects, OSGi configurations are over-used or are used for purposes that can be better served by content policies. So, instead of showing you how to set up an OSGi configuration using SCR annotations, I’ll just conclude with an encouragement to take another look at content policies.

  • Use limited option edit configurations for changes that every author needs to make to a component
  • Use content policies for almost everything else
  • And use OSGi configurations very sparingly, as they affect your entire AEM instance.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.