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
- Create a folder under
/apps/my-company/granite/rendercondition/metadata-schema
- 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 onMetadataSchemaRenderConditionUtil
(see impl below). - Add the following java utility class:
com.mycompany.core.utils.MetadataSchemaRenderConditionUtil
- 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 withsling:resourceType
pointing to my render condition and I’ve also suppliedallowedAssetPath
param. - 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 🙂
- Enjoy!
I hope you found this post helpful. Subscribe to get helpful posts each week!