Custom fields in tag dialogs for Touch UI

It’s well known about how to administer tags, and how to use them in our application. We can also deliver application tags with an application source code or as a content package.

The tag definition is located in XML file .content.xml, for example /etc/tags/<some_project>/.content.xml and its structure is as the following:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:description="Description of entertainment tag"
jcr:primaryType="cq:Tag"
jcr:title="Entertainment"
sling:resourceType="cq/tagging/components/tag"/>

What if we need to add custom properties to these tags, eg. property like matureContent? It’s simple. Add it to the tag definition:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:description="Description of entertainment tag"
jcr:primaryType="cq:Tag"
jcr:title="Entertainment"
matureContent="No"
sling:resourceType="cq/tagging/components/tag"/>

and in your Java code you can use it like this

// ...
Resource myTagResource = request.getResourceResolver().resolve(myTag.getPath());
ValueMap valueMap = myTagResource.adaptTo(ValueMap.class);
String matureContent = valueMap.get("matureContent", String.class);
// ...

When you open the edit dialog for this tag, you will not see a field for matureContent property, so you will have to add one.

For AEM 6.3, the tag dialog is placed in /libs/cq/tagging/gui/content/tags/tagedit. You can find nodes for title and description under this node /libs/cq/tagging/gui/content/tags/tagedit/jcr:content/body/items/form/items/wizard/items/editStep/items/fixedColumns/items/fixedColumn1/items, and JavaScript code that handles administration of tags here /libs/cq/tagging/gui/components/tagedit/clientlibs/tagedit/js/tagedit.js.

Off course, it is not recommended to modify files in /libs folder so we will rely on Sling Resource Merger here. We will just recreate the structure of nodes cq/tagging/gui/content/tags/tagedit/jcr:content/body/items/form/items/wizard/items/editStep/items/fixedColumns/items/fixedColumn1/items from /libs to /apps and copy cq/tagging/gui/components/tagedit/clientlibs/tagedit from /libs to /apps folder. Under node /apps/cq/tagging/gui/content/tags/tagedit/jcr:content/body/items/form/items/wizard/items/editStep/items/fixedColumns/items/fixedColumn1/items we will add node matureContent which represents our custom field:

matureContent node
matureContent node

When you save this change, clean the browser’s cache and open the tag dialog. You will see your custom field Mature Content:

Tag dialog with Mature Content custom field
Tag dialog with Mature Content custom field

Unfortunately, you cannot see the value “No” in that field so we need to open the file /apps/cq/tagging/gui/components/tagedit/clientlibs/tagedit/js/tagedit.js and in that file:

  • find AJAX GET call that loads properties (as JSON) for this tag
  • find a piece of code that populates the values for title and description
    $("#tagtitle").val(res["jcr:title"]);
    $("#tagdescription").val(res["jcr:description"]);
    
  • add the line for your Mature Content field
    $("#tagmaturecontent").val(res["matureContent"]);
    

Save the file, clean the browser’s cache and open the dialog again for the tag Entertainment and you will see the value “No” in field Mature Content. You can change that value to “Yes” for example and submit the form.

There is just one more problem. If you check in web console you will notice that on every submit of the tag dialog, two POST requests are sent and sometimes the second one returns error response. This happens because tagedit.js code is loaded from both lib and apps folder.

In order to fix this problem, do the following:

  • open CRXDELite
  • find folder /apps/cq/tagging/gui/components/tagedit/clientlibs/tagedit
  • change a value of property categories to something else, eg. to apps.cq.tagging.touch.tagedit
  • find node /apps/cq/tagging/gui/content/tags/tagedit/jcr:content/head/clientlibs and in property categories change cq.tagging.touch.tagedit to apps.cq.tagging.touch.tagedit
  • save the changes, clean browser’s cache, open tag dialog, click on Submit and … that’s it.