Skip to main content

Adobe

How to Show/Hide Metadata Schema Field Based on Asset Path

If you have not read my post explaining how to show/hide page properties based on a template in AEM 6.4  you may want to stop and read that before this one. Especially the “Granite Render Condition” section as it is the basis for this post. Now onto the good stuff!

Banner Photo by Glenn Carstens-Peters on Unsplash

The Use Case

I’m going to walk you through how to show/hide an Asset Metadata Schema field based on the asset location. In this specific case, I want to show certain fields for assets under /content/dam/community and hide fields for all other assets.

Caution Before Proceeding

This post assumes, as it was put in this tweet, that the creation of the Metadata Schema is a developer task. In my specific case, it is. But in most cases, the Metadata Schemas should be created and maintained by authors.

Using a Different Metadata Schema

You could create a new metadata schema, add the community fields and apply that schema to the /content/dam/community path only. While a good solution, it means you have to create a new schema. While that’s an OK approach, I have a better one!
 

Using Granite Render Condition

  • You can read my other post and learn about Granite Render Condition. That article also contains links to articles and documentation.
  • This was developed and tested on AEM 6.4 only. Although, it would work on older versions.

In AEM 6.4, when you edit asset properties, the metadata editor opens. For example, if you have an asset under /content/dam/my-asset.jpg, and try to edit that asset’s property, the metadata editor URL that will open is: http://localhost:4502/mnt/overlay/dam/gui/content/assets/metadataeditor.external.html?_charset_=utf-8&item=/content/dam/my-asset.jpg
With that information, we can build the following render condition:

note: In this example, I use my-company as the project folder under apps, you can change that with your own path.

The Process

  1. Create a folder under /apps/my-company/granite/rendercondition/metadata-schema
  2. Under that folder, create metadata-schema.jsp and enter the following:
    <%@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.MetadataSchemaRenderConditionUtil,
              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/metadata-schema
       :rendercondition:
       A condition that renders asset metadata schema fields based on the asset path.
       It has the following content structure:
       .. gnd:gnd::
          [granite:RenderConditionsMetadataSchema]
          /**
           * The asset path to match
           */
          - allowedAssetPath (String)
    ###--%>
    <sling:defineObjects/>
    <%
    final ComponentHelper cmp = new ComponentHelper(pageContext);
    Config cfg = cmp.getConfig();
    String path = cfg.get("allowedAssetPath", "");
    boolean vote = MetadataSchemaRenderConditionUtil.isDecendantAsset(slingRequest, request, path);
    request.setAttribute(RenderCondition.class.getName(), new SimpleRenderCondition(vote));
    %>

    As you can see, I am getting the both the servlet and the sling requets, as well as expecting allowedAssetPath property. Also, I depend on MetadataSchemaRenderConditionUtil (see impl below).

  3. Add the following java utility class: com.mycompany.core.utils.MetadataSchemaRenderConditionUtil
  4. Now that we have the code, we can use the render condition on a metadata schema field:
    <custom-document-tag
        cq:showOnCreate="{Boolean}true"
        jcr:primaryType="nt:unstructured"
        sling:resourceType="dam/gui/components/admin/schemafield"
        cq-msm-lockable="cq:tags"
        fieldLabel="Custom Community Tag Field"
        metaType="tags"
        multiple="false"
        name="./jcr:content/metadata/customCommunityTag"
        resourceType="cq/gui/components/coral/common/form/tagfield"
        rootPath="/content/cq:tags">
        <granite:data
            jcr:primaryType="nt:unstructured"
            requiredCascading="default"
            visibilityCascading="default"/>
        <granite:rendercondition
            jcr:primaryType="nt:unstructured"
            sling:resourceType="my-company/granite/rendercondition/metadata-schema"
            allowedAssetPath="/content/dam/community"/>
    </custom-document-tag>

    You can see, I added a granite:rendercondition node with sling:resourceType pointing to my render condition and I’ve also supplied allowedAssetPath param.

  5. Now this field will only show for assets that are under /content/dam/community

    I know that the logic is simple enough to be written in the JSP without the additional class, but I wanted testable code 🙂

  6. Enjoy!

I hope you found this post helpful. Subscribe to get helpful posts each week!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Ahmed Musallam, Adobe Technical Lead

Ahmed is an Adobe Technical Lead and expert in the Adobe Experience Cloud.

More from this Author

Categories
Follow Us