How to show/hide page properties based on template in AEM 6.4 | Perficient Digital

How to show/hide page properties based on template in AEM 6.4

Recently, we had a requirement to show specific page properties for community pages that are based on the community editable template. As you know, in AEM 6.4, editable templates usually share the same page component, which means the same page properties dialog. Now, you could create a new page component (community-page) and inherit the master page component then ad the desired page properties. But there is another way!

Photo by Max van den Oetelaar on Unsplash

Granite Render Condition  

The granite render conditions allow you to show/hide resources based on a condition. Nate Yolles has an excellent post on the topic. Additionally there is a path based ACS commons render condition.

Reading the render condition docs and Nate Yolles post are essential to understanding the rest of this article.

 

Handling my specific use-case

back to my use case, I want to hide page property resources based on the template of the page authored. In AEM 6.4, page properties are handled in a specific UI with a specific url:

http://localhost:4502/mnt/overlay/wcm/core/content/sites/properties.html?item=/content/my-company/my-page

Now, I just need to write a render condition that will obtain the “item” param (page path) then from there I can get the page and its template and compare it to my specific template path. Here is what I arrived at:

<%@include file="/libs/foundation/global.jsp"%>
<%@page session="false"
        import="com.adobe.granite.ui.components.Config,
          com.adobe.granite.ui.components.rendercondition.RenderCondition,
          com.adobe.granite.ui.components.rendercondition.SimpleRenderCondition,
          com.mycompany.core.utils.TemplateRenderConditionUtil,
          org.apache.sling.api.resource.Resource,
          org.apache.sling.api.resource.ValueMap,
          com.adobe.granite.ui.components.ComponentHelper,
          com.adobe.granite.xss.XSSAPI,
          com.day.cq.i18n.I18n"%>
<%--###

Template
======

.. granite:servercomponent:: /apps/my-company/granite/rendercondition/template
   :rendercondition:

   A condition that renders page properties based on page template path

   It has the following content structure:

   .. gnd:gnd::

      [granite:RenderConditionsTemplate]

      /**
       * The template path to match
       */
      - templatePath (String)
###--%>
<sling:defineObjects/>
<%

final ComponentHelper cmp = new ComponentHelper(pageContext);
Config cfg = cmp.getConfig();
String path = cfg.get("templatePath", "");
boolean vote = TemplateRenderConditionUtil.isTemplate(slingRequest, request, path);
request.setAttribute(RenderCondition.class.getName(), new SimpleRenderCondition(vote));
%>

As you can see, I get the configured templatePath then pass it to TemplateRenderConditionUtil#isTemplate.

here is the code for TemplateRenderConditionUtil

Please note: the code here should be straight-forward to follow assuming you are familiar with java 8 lambdas.

 

package com.mycompany.core.utils;

import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.Template;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;


public class TemplateRenderConditionUtil {

  private static final String PAGE_PROPERTIES = "wcm/core/content/sites/properties";

  public static boolean isTemplate(
    SlingHttpServletRequest slingHttpServletRequest,
    HttpServletRequest httpServletRequest,
    String templatePath) {

    // error if any of the passed params is null.
    if (slingHttpServletRequest == null
        || httpServletRequest == null
        || StringUtils.isBlank(templatePath)) {
      throw new IllegalArgumentException("One of the passed parameters is null.");
    }

    // the dialog is a page properties dialog
    if (StringUtils.contains(httpServletRequest.getPathInfo(), PAGE_PROPERTIES)) {

      // get the actual page path
      String pagePath = httpServletRequest.getParameter("item");

      // get page template path and check it
      return Optional.ofNullable(slingHttpServletRequest.getResourceResolver())
          .map(resourceResolver -> resourceResolver.getResource(pagePath))
          .map(pageResource -> pageResource.adaptTo(Page.class))
          .map(Page::getTemplate)
          .map(Template::getPath)
          .map(path -> StringUtils.contains(path, templatePath))
          .orElse(false);
    }
    return false;
  }

}

 

Now you can add a granite:rendercondition node under any of your properties to show/hide them based on template path. Here is an example:

<community jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/fieldset"
    jcr:title="Community Properties">
    <items jcr:primaryType="nt:unstructured">
        <communityName
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
            disabled="{Boolean}true"
            emptyText="Community ShortName"
            fieldLabel="Community Shortname"
            name="./communityShortname" />
        <communityColor
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/coral/foundation/form/select"
            fieldLabel="Community Color"
            name="./communityColor">
            <datasource
                jcr:primaryType="nt:unstructured"
                sling:resourceType="acs-commons/components/utilities/genericlist/datasource"
                path="/etc/acs-commons/lists/community-color" />
        </communityColor>
    </items>
    <granite:rendercondition
        jcr:primaryType="nt:unstructured"
        sling:resourceType="my-company/granite/rendercondition/template"
        templatePath="/conf/my-company/settings/wcm/templates/community-page"/>
</community>

my community fieldset will now only show for pages that are created from template: /conf/my-company/settings/wcm/templates/community-page

Leave a Reply