Problem Statement:
How can I utilize component policies chosen at the template level to manage the visibility of specific field content within the component’s Sling model code?
Introduction:
AEM has integrated component policies as a pivotal element of the editable template feature. This functionality empowers both authors and developers to provide options for configuring the comprehensive behavior of fully-featured components, including deciding which fields to display, hide, or customize. This configuration is carried out at the template level, facilitating reuse across various templates or template-specific customizations.
Furthermore, AEM introduces a robust styling feature that empowers frontend developers to manage the visual appearance and user interface of components. This grants authors the capability to tailor the look and feel of the component.
Let’s illustrate this with an AEM core component as an example:
Requirement:
In a previous discussion, we outlined a step-by-step process for Accessing Component Policies in AEM at the Component Dialog Level and Sightly code. However, a situation has arisen a question where the field has already been authored on multiple pages, and we now need to avoid displaying this field on pages where it has already been authored. How can this be achieved using the Sling model?
Solution:
This can be achieved at the Sling model level in two ways:
- By adapting to Out of the Box (OOTB) “ContentPolicyManager” as shown below:
package com.adobe.cq.wcm.core.components.internal.models.v1;
import com.adobe.cq.export.json.ExporterConstants;
import com.adobe.cq.wcm.core.components.models.Teaser;
import com.day.cq.wcm.api.designer.Style;
import com.day.cq.wcm.api.policies.ContentPolicy;
import com.day.cq.wcm.api.policies.ContentPolicyManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.*;
@Model(adaptables = SlingHttpServletRequest.class, resourceType = TeaserModel.RESOURCE_TYPE)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME , extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class TeaserModel {
public final static String RESOURCE_TYPE = "core/wcm/components/teaser/v1/teaser";
@Self
private SlingHttpServletRequest request;
@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
private String pretitle;
@SlingObject
protected Resource resource;
private boolean pretitleHidden = false;
public String getPretitle() {
ContentPolicyManager policyManager = request.getResourceResolver().adaptTo(ContentPolicyManager.class);
if (policyManager != null) {
ContentPolicy currentPolicy = policyManager.getPolicy(resource, request);
if (currentPolicy != null) {
pretitleHidden = currentPolicy.getProperties().get(Teaser.PN_PRETITLE_HIDDEN, pretitleHidden);
}
}
if(!pretitleHidden){
return pretitle;
}
return StringUtils.EMPTY;
}
}
2. By Injecting Out of the Box (OOTB) “currentStyle” using “ScriptVariable” as shown below:
package com.adobe.cq.wcm.core.components.internal.models.v1;
import com.adobe.cq.export.json.ExporterConstants;
import com.adobe.cq.wcm.core.components.models.Teaser;
import com.day.cq.wcm.api.designer.Style;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
import org.apache.sling.models.annotations.injectorspecific.ScriptVariable;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
@Model(adaptables = SlingHttpServletRequest.class, resourceType = TeaserModel.RESOURCE_TYPE)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME , extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class TeaserModel {
public final static String RESOURCE_TYPE = "core/wcm/components/teaser/v1/teaser";
@ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
private String pretitle;
@ScriptVariable
protected Style currentStyle;
private boolean pretitleHidden = false;
public String getPretitle() {
pretitleHidden = currentStyle.get(Teaser.PN_PRETITLE_HIDDEN, pretitleHidden);
if(!pretitleHidden){
return pretitle;
}
return StringUtils.EMPTY;
}
}
One significant advantage of employing the Sling model for this requirement is the flexibility it offers in implementing and manipulating business logic before delivering results. As demonstrated in the example above, injecting ScriptVariable allows for a more streamlined approach, eliminating the need for extra lines of code such as adaptation, resource resolution, and null checks. The Sling model code dynamically manages the visibility of the “pretitle” field based on the “pretitleHidden” property in the “currentStyle.”







