How to copy 100 tags to a new path? | Community
Skip to main content
Level 2
February 12, 2025
Solved

How to copy 100 tags to a new path?

  • February 12, 2025
  • 2 replies
  • 781 views

On-prem AEM 6.5, SPA, Angular 9, Bootstrap 4

We have two groups of tags.  One group is used to populate a State dropdown in an Adaptive Form.  Another group is used to populate a Country dropdown in an Adaptive Form.  I would like to copy (not move) these two groups of tags to a different path.  I can't use a global taxonomy for these tags because administrators have locked down the ability to create globally available tags and there are too many tags to manually recreate for every new path.

What is the easiest method for accomplishing this task as a non-administrator?

 

Best answer by ayush-anand

Hi @dpkhmhs ,

 

You can create a simple Groovy script for this. Below is a sample code, though I haven’t tested it myself.

 

import org.apache.sling.api.resource.Resource import org.apache.sling.api.resource.ResourceResolver import org.apache.sling.api.scripting.SlingScriptHelper import org.apache.sling.api.wrappers.ValueMapDecorator import org.apache.sling.api.resource.ModifiableValueMap import org.apache.sling.api.resource.ValueMap import org.apache.sling.api.resource.Resource import org.apache.sling.api.resource.ResourceUtil import org.apache.sling.api.resource.ResourceMetadata import org.apache.sling.api.resource.Resource import org.apache.sling.api.resource.ResourceResolver import com.day.cq.tagging.Tag import com.day.cq.tagging.TagManager import org.apache.sling.api.resource.Resource // Input Parameters String sourcePath = "/content/cq:tags/old-path" // Source tag path String targetPath = "/content/cq:tags/new-path" // Target tag path // Retrieve the source tag TagManager tagManager = resourceResolver.adaptTo(com.day.cq.tagging.TagManager); Tag sourceTag = tagManager.resolve(sourcePath) // Function to copy a tag and its hierarchy def copyTagHierarchy(Tag sourceTag, String targetPath, TagManager tagManager) { // Check if source tag exists if (sourceTag == null) { log.error("Source tag does not exist.") return } // Create a new tag in the target path String targetTagName = targetPath + "/" + sourceTag.getName() Tag targetTag = tagManager.createTag(targetTagName, targetTagName, targetTagName) // Copy properties (optional) from the source to the target tag copyTagProperties(sourceTag, targetTag) // Copy the child tags recursively sourceTag.listChildren().each { childTag -> // Recursively copy child tags copyTagHierarchy(childTag, targetTagName, tagManager) } } // Function to copy tag properties, excluding system properties def copyTagProperties(Tag sourceTag, Tag targetTag) { // Get the properties of the source tag (as ValueMap) Resource sourceResource = resourceResolver.getResource(sourceTag.getPath()) if (sourceResource == null) { log.error("Source resource does not exist for tag: " + sourceTag.getPath()) return } ModifiableValueMap sourceProperties = sourceResource.adaptTo(ModifiableValueMap.class) // Get the target resource Resource targetResource = resourceResolver.getResource(targetTag.getPath()) if (targetResource == null) { log.error("Target resource does not exist for tag: " + targetTag.getPath()) return } ModifiableValueMap targetProperties = targetResource.adaptTo(ModifiableValueMap.class) // List of system properties to exclude from copy def excludedProperties = [ "jcr:createdBy", "jcr:created", "jcr:lastModified", "jcr:lastModifiedBy" ] // Copy properties from source to target, excluding system properties if (sourceProperties != null && targetProperties != null) { sourceProperties.each { key, value -> // Exclude system properties if (!excludedProperties.contains(key)) { targetProperties.put(key, value) } } // Commit the changes resourceResolver.commit() } } // Start the copy process copyTagHierarchy(sourceTag, targetPath, tagManager) log.info("Tag hierarchy copied successfully from ${sourcePath} to ${targetPath}")

 

Regards,

Ayush

2 replies

Harwinder-singh
Community Advisor
Community Advisor
February 12, 2025

@dpkhmhs You can create a simple groovy script to copy these tags under the new path. 

FYI, you will need JCR permissions to atleast create nodes to get this done. Check if there is a service user that you can use for this.

If you dont have grrovy console installed in your environment, you can create a managed controlled process (MCP) to do this.

dpkhmhsAuthor
Level 2
February 12, 2025

Thanks for the reply @harwinder-singh. I installed the groovy console (15.1.0) in my local instance and have admin access.  I opened a few of the sample scripts and it looks like gibberish to me.  The Groovy syntax is fine as I'm a Java developer.  However, I'm not an AEM developer and would appreciate some hints to create the "simple groovy script" you mentioned to accomplish my task.  Thanks!

Avinash_Gupta_
Community Advisor and Adobe Champion
Community Advisor and Adobe Champion
February 13, 2025
ayush-anand
ayush-anandAccepted solution
Level 4
February 13, 2025

Hi @dpkhmhs ,

 

You can create a simple Groovy script for this. Below is a sample code, though I haven’t tested it myself.

 

import org.apache.sling.api.resource.Resource import org.apache.sling.api.resource.ResourceResolver import org.apache.sling.api.scripting.SlingScriptHelper import org.apache.sling.api.wrappers.ValueMapDecorator import org.apache.sling.api.resource.ModifiableValueMap import org.apache.sling.api.resource.ValueMap import org.apache.sling.api.resource.Resource import org.apache.sling.api.resource.ResourceUtil import org.apache.sling.api.resource.ResourceMetadata import org.apache.sling.api.resource.Resource import org.apache.sling.api.resource.ResourceResolver import com.day.cq.tagging.Tag import com.day.cq.tagging.TagManager import org.apache.sling.api.resource.Resource // Input Parameters String sourcePath = "/content/cq:tags/old-path" // Source tag path String targetPath = "/content/cq:tags/new-path" // Target tag path // Retrieve the source tag TagManager tagManager = resourceResolver.adaptTo(com.day.cq.tagging.TagManager); Tag sourceTag = tagManager.resolve(sourcePath) // Function to copy a tag and its hierarchy def copyTagHierarchy(Tag sourceTag, String targetPath, TagManager tagManager) { // Check if source tag exists if (sourceTag == null) { log.error("Source tag does not exist.") return } // Create a new tag in the target path String targetTagName = targetPath + "/" + sourceTag.getName() Tag targetTag = tagManager.createTag(targetTagName, targetTagName, targetTagName) // Copy properties (optional) from the source to the target tag copyTagProperties(sourceTag, targetTag) // Copy the child tags recursively sourceTag.listChildren().each { childTag -> // Recursively copy child tags copyTagHierarchy(childTag, targetTagName, tagManager) } } // Function to copy tag properties, excluding system properties def copyTagProperties(Tag sourceTag, Tag targetTag) { // Get the properties of the source tag (as ValueMap) Resource sourceResource = resourceResolver.getResource(sourceTag.getPath()) if (sourceResource == null) { log.error("Source resource does not exist for tag: " + sourceTag.getPath()) return } ModifiableValueMap sourceProperties = sourceResource.adaptTo(ModifiableValueMap.class) // Get the target resource Resource targetResource = resourceResolver.getResource(targetTag.getPath()) if (targetResource == null) { log.error("Target resource does not exist for tag: " + targetTag.getPath()) return } ModifiableValueMap targetProperties = targetResource.adaptTo(ModifiableValueMap.class) // List of system properties to exclude from copy def excludedProperties = [ "jcr:createdBy", "jcr:created", "jcr:lastModified", "jcr:lastModifiedBy" ] // Copy properties from source to target, excluding system properties if (sourceProperties != null && targetProperties != null) { sourceProperties.each { key, value -> // Exclude system properties if (!excludedProperties.contains(key)) { targetProperties.put(key, value) } } // Commit the changes resourceResolver.commit() } } // Start the copy process copyTagHierarchy(sourceTag, targetPath, tagManager) log.info("Tag hierarchy copied successfully from ${sourcePath} to ${targetPath}")

 

Regards,

Ayush