Granite Render Conditions In AEM – Show/Hide Field Properties

Hello Dev, In this article you are going to learn Granite Rendering Condition in AEM, after this article you’ll understand that how you can use OOTB granite render conditions or even you can create your own custom granite render condition based on your project requirements.

What is Granite Render Condition in AEM ?

Let me tell you first about render condition theory then you will better understand granite render condition. In AEM we can render(show/hide) content, elements and author-able field properties (which usually we author from author touch UI) based on conditions. So if we want to show/hide content or element in AEM for the end users then it is known as Render Condition and for this we can use HTL, backend or even scripting language. But Granite Render Condition works in author touch UI environment, it means, we can show/hide field properties which comes on dialog. So if we want to show/hide a particular field property of a dialog based on some conditions then we need to use Granite Render Condition.

Where we require Granite Render Conditions ?

There are many situation where you might want to conditionally display a field of a dialog. Some examples are mentioned below:

  • Displaying a field in page properties depending on template
  • Displaying a field depending on the user group
  • Displaying a field if the page is locked

AEM gives many OOTB granite render conditions which meets your almost requirement, but as I said almost not all. So to meets all your requirements we need to create our own custom granite render conditions. In this article we’ll learn how can we use OOTB granite render condition and also how can we create our own custom render conditions.

Lets Explore and use OOTB Granite Render Condition

/libs/granite/ui/components/coral/foundation/renderconditions

this is the location where all our OOTB granite render conditions are available , we can directly use any of the condition as per our requirements.

and : it can be used when two condition need to check with AND operator (both condition should be true)

same not for NOT and or for OR used,

Feature: A condition that decides based on :javadoc:Sling’s Feature Flag <org/apache/sling/featureflags/package-summary.html>.

Privilege : this can be used when we want some user, group based condition. like hiding field base on group means a particular user group can see and modify.

Simple : this is most used render condition which take only one expression and based on that expression condition it render or not.

Lets, take an example so that you can understand and able to implement in your work. I like to play with cookies so why not show/hide field based on cookies value, you think like, why even required these type of conditions 😂, so suppose a cookies is set dynamically by username, and we can only this user can see and configured, I know I know, this type of requirement usually not coming but here I am taking example only

Hide/Show field based on Cookies value

<cookiesField
     jcr:primaryType="nt:unstructured"
     sling:resourceType="granite/ui/components/foundation/form/textfield"
     fieldLabel="This field is only for Shahid"
     name="./cookiesField">
     <granite:rendercondition
             jcr:primaryType="nt:unstructured"
             sling:resourceType="granite/ui/components/coral/foundation/renderconditions/simple"
             expression="${cookie.username.value == 'Shahid'}"/>
</cookiesField>

When Cookie is present :

In above code, everything looks similar to normal field but here you can see within the field, there is an extra tag which is responsible to make this field a granite render condition field. It means when condition (expression) match then cookiesField will be visible otherwise not.

granite:rendercondition to show/hide field and this tag is necessary.

sling:resourceType=”granite/ui/components/coral/foundation/renderconditions/simple” this is the predefined render which using here as you can see many other conditions are there.

expression This contains condition expressions and name can be anything as you want like expressionshahid=”${cookie.username.value == ‘Shahid’}”, conditions=”${cookie.username.value == ‘Shahid’}” etc.

Many more ready-made fields are here, you can try and use https://gist.github.com/nateyolles/eec2f56acc7153fe9fb7dd6637e8f7ad

Custom Granite Render Condition

So, as I said earlier we can create custom granite render conditions to meets our requirements.

Lets show/hide property based on template.

Assume Problem :

I want to show a field in page properties only when a particular template is used to create that page

Codes/Solution: I am taking I have a template name Home Page (home-page).

Xml code :

<ShowInHomeTemplate
        cq:showOnCreate="{Boolean}true"
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
        fieldLabel="Home Page Template Field"
        name="./homePageTemplateField"
        required="{Boolean}false">
        <granite:rendercondition
                jcr:primaryType="nt:unstructured"
                sling:resourceType="wknd/components/renderconditions/template"
                 allowedTemplateTypes="[/conf/wknd/settings/wcm/templates/home-page]"/>
</ShowInHomeTemplate>

add this code in your page component

HTL code :

<div data-sly-use = "com.adobe.aem.guides.wknd.core.models.TemplateRenderCondition"></div>

I have created folder and this file under UI apps, you can follow same and within the HTML file we will call our render condition sling model

Java Sling Model Code :

package com.adobe.aem.guides.wknd.core.models;

import java.util.List;
import javax.annotation.PostConstruct;

import com.adobe.granite.ui.components.rendercondition.RenderCondition;
import com.adobe.granite.ui.components.rendercondition.SimpleRenderCondition;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.api.NameConstants;

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.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Model(
        adaptables = {SlingHttpServletRequest.class, Resource.class},
        defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class TemplateRenderCondition{


    private final Logger logger = LoggerFactory.getLogger(getClass());

    protected static final String REQUEST_PARAM_STRING = "item";

    @Self
    private SlingHttpServletRequest request;

    @ValueMapValue
    protected List<String> allowedTemplateTypes;

    @ValueMapValue
    protected String isComponent;

    protected Boolean show = false;

    @PostConstruct
    protected void init() {
        try {
            String suffix = request.getRequestPathInfo().getSuffix();
            String queryParam = request.getParameter(REQUEST_PARAM_STRING);

            for (String allowedTemplateType : allowedTemplateTypes) {
                if(StringUtils.isNotEmpty(suffix) && allowedTemplateType.equals(suffix)) {
                    show = true;
                } else if(StringUtils.isNotEmpty(queryParam)) {
                    Resource pageResource = request.getResourceResolver().getResource(queryParam.concat("/").concat(JcrConstants.JCR_CONTENT));
                    if(pageResource != null) {
                        String templatePath = pageResource.getValueMap().get(NameConstants.NN_TEMPLATE, "");
                        if (templatePath.equals(allowedTemplateType)) {
                            show = true;
                        }
                    }
                } else if(isComponent != null && isComponent.equals("true")) {
                    Resource pageResource = request.getResourceResolver().getResource(suffix.substring(0, suffix.indexOf("/jcr:content")).concat("/").concat(JcrConstants.JCR_CONTENT));
                    if(pageResource != null) {
                        String templatePath = pageResource.getValueMap().get(NameConstants.NN_TEMPLATE, "");
                        if (templatePath.equals(allowedTemplateType)) {
                            show = true;
                        }
                    }
                }
            }

        } catch (IllegalArgumentException e) {
            logger.error("Exception while procession the request: ", e);
        }
        request.setAttribute(RenderCondition.class.getName(), new SimpleRenderCondition(show));
    }
}

in the above java code we simple compare current page template and what we pass in expression ( allowedTemplateTypes ) and based on these, we compare and have set a request attribute true or false based on condition check to the Java SimpleRenderCondition class, and this class is provided by AEM api.

Now you can see, the page which have created using home page template they have this field. main image credit to medium
Any query ? feel free to comment below. Thanks

Leave a Comment