Adobe Tech Blog

News, updates, and thoughts related to Adobe, developers, and technology.

Follow publication

Apache Sling Pipes: Real World Examples

Kaushal Mall
Adobe Tech Blog
Published in
3 min readJul 28, 2020

  • Do you want to move your AEM tags from /etc/tags to /content/cq:tags?
  • Do you want to update the cq:designPath property across 1,000s of pages is AEM because the design was moved from /etc/design to /apps/settings?
  • Have you heard about Sling Pipes but can’t find any real world examples on how to make it happen in AEM?
  • Read on for three real world scenarios that will hopefully help you unlock the power Sling Pipes for most of your use cases.

Pre-requisite

Unfortunately, the Sling Pipes bundle is not included AEM OOTB. Before you do anything else, please install the Sling Pipes and Sling Query bundles on your AEM instance — both of these are available on Maven Central.

Calling your pipe

All pipes in this blog can we accessed via POST call, like:

curl -u admin:admin -X POST http://localhost:4502/path/to/mypipe.json

Moving AEM tags

Sling Pipe to move tags from /etc to /content

  1. Creates the cq:tags folder
  2. Add properties to the folder
  3. Finds all the cq:Tag nodes under /etc/tags.
  4. Moves them by replacing the /etc/tags in the path with /content/cq:tags.
"moveTagsPipe":{
"jcr":"primaryType":"sling:Folder",
"jcr":"description":"This Sling Pipe moves tags from the path defined in the tags-root to /content ",
"sling":"resourceType":"slingPipes/container",
"conf":{
"createTagsNode":{
"jcr":"primaryType":"nt:unstructured",
"expr":"/content/cq:tags",
"path":"/content/cq:tags",
"nodeType":"sling:Folder",
"sling":"resourceType":"slingPipes/path"
},
"writeTagNodeProperties":{
"jcr":"primaryType":"nt:unstructured",
"sling":"resourceType":"slingPipes/write",
"conf":{
"jcr":"primaryType":"nt:unstructured",
"jcr":"title":"Tags",
"hidden":true,
"sling":"target":"/tagging",
"sling":"resourceType":"sling:redirect",
"languages":[
"en",
"de",
"es",
"fr",
"it",
"pt_br",
"zh_cn",
"zh_tw",
"ja",
"ko_kr"
]
}
},
"findTags":{
"jcr":"primaryType":"sling:Folder",
"expr":"/jcr:root/etc/tags//element(*, cq:Tag)",
"sling":"resourceType":"slingPipes/xpath"
},
"moveTags":{
"jcr":"primaryType":"nt:unstructured",
"expr":"${path.findTags.replace(" "/etc/tags" ", " "/content/cq":"tags" ")}",
"sling":"resourceType":"slingPipes/mv"
}
}
}

Updating a single value property

  1. Runs a query to find all cq:Page nodes where the cq:designPath property is set to /etc/designs/mydesign.
  2. Gets the jcr:content node of the page.
  3. Updates the property with the path under /apps/settings/….
"designPathUpdatePipe":{
"jcr":"primaryType":"sling:Folder",
"sling":"resourceType":"slingPipes/container",
"conf":{
"jcr":"primaryType":"sling:OrderedFolder",
"findNodes":{
"jcr":"primaryType":"sling:Folder",
"expr":"/jcr:root/content//element(*, cq:Page)[(jcr:content/@cq:designPath = '/etc/designs/mydesign')]",
"sling":"resourceType":"slingPipes/xpath"
},
"pageContentNode":{
"jcr":"primaryType":"nt:unstructured",
"expr":"#'jcr:content'",
"sling":"resourceType":"slingPipes/children"
},
"updateProperty":{
"jcr":"primaryType":"nt:unstructured",
"sling":"resourceType":"slingPipes/write",
"conf":{
"jcr":"primaryType":"nt:unstructured",
"cq":"designPath":"/apps/settings/wcm/designs/mydesign"
}
}
}
}

Updating a multi-value property

  1. Find all cq:Page nodes where the cq:cloudserviceconfigs property exists.
  2. Gets the jcr:content child.
  3. Gets each property of the multivalue property; for each value.
  4. On the path of the node returned by the “findNodes” pipe, writes a new property “cloudServiceConfigTmp”, by replacing the /etc/cloudservices in the path with /conf/….
  5. Removes the cq:cloudserviceconfigs property.
  6. Gets each property of the multivalue property; for each value.
  7. Writes the value, as is in the new cq:cloudserviceconfigs property
  8. Removes the temp property.
"cloudServiceConfigsCopyPipe":{
"jcr":"primaryType":"sling:Folder",
"sling":"resourceType":"slingPipes/container",
"conf":{
"jcr":"primaryType":"sling:OrderedFolder",
"findNodes":{
"jcr":"primaryType":"sling:Folder",
"expr":"/jcr:root/content//element(*, cq:Page)[(jcr:content/@cq:cloudserviceconfigs)]",
"sling":"resourceType":"slingPipes/xpath"
},
"pageContentNode":{
"jcr":"primaryType":"nt:unstructured",
"expr":"#'jcr:content'",
"sling":"resourceType":"slingPipes/children"
},
"cloudServiceConfig":{
"jcr":"primaryType":"nt:unstructured",
"path":"cq:cloudserviceconfigs",
"sling":"resourceType":"slingPipes/multiProperty"
},
"writeTempProperty":{
"jcr":"primaryType":"nt:unstructured",
"path":"${path.findNodes}/jcr:content",
"sling":"resourceType":"slingPipes/write",
"conf":{
"jcr":"primaryType":"nt:unstructured",
"cloudServiceConfigTmp":"+[${cloudServiceConfig.replace("/etc/cloudservices","/conf/global/settings/cloudconfigs")}]"
}
},
"removeProperty":{
"jcr":"primaryType":"nt:unstructured",
"path":"${path.findNodes}/jcr:content/cq:cloudserviceconfigs",
"sling":"resourceType":"slingPipes/rm"
},
"cloudServiceConfigTmp":{
"jcr":"primaryType":"nt:unstructured",
"path":"${path.findNodes}/jcr:content/cloudServiceConfigTmp",
"sling":"resourceType":"slingPipes/multiProperty"
},
"writeProperty":{
"jcr":"primaryType":"nt:unstructured",
"path":"${path.findNodes}/jcr:content",
"sling":"resourceType":"slingPipes/write",
"conf":{
"jcr":"primaryType":"nt:unstructured",
"cq":"cloudserviceconfigs":"+[${cloudServiceConfigTmp}]"
}
},
"removeTmpProperty":{
"jcr":"primaryType":"nt:unstructured",
"path":"${path.findNodes}/jcr:content/cloudServiceconfigTmp",
"sling":"resourceType":"slingPipes/rm"
}
}
}

Updating a single-value property

  1. Find all the nodes under /content where the sling:resourceType property is dam/components/scene7/dynamicmedia
  2. For each node, update the s7ViewerPreset property to replace /etc/dam/presets with /conf/global/settings/dam/dm/presets
s7ViewerPresetUpdatePipe:{
"jcr":"primaryType":"sling:Folder",
"jcr":"createdBy":"admin",
"status":"finished",
"jcr":"created":"Wed Nov 11 2020 20:44:06 GMT-0700",
"statusModified":"Wed Nov 11 2020 22:20:47 GMT-0500",
"sling":"resourceType":"slingPipes/container",
"conf":{
"jcr":"primaryType":"sling:OrderedFolder",
"jcr":"createdBy":"admin",
"jcr":"created":"Wed Nov 11 2020 20:44:06 GMT-0700",
"one":{
"jcr":"primaryType":"sling:OrderedFolder",
"jcr":"createdBy":"admin",
"jcr":"created":"Wed Nov 11 2020 20:44:06 GMT-0700",
"path":"/content",
"sling":"resourceType":"slingPipes/base"
},
"findNodes":{
"jcr":"primaryType":"sling:Folder",
"jcr":"createdBy":"admin",
"jcr":"created":"Wed Nov 11 2020 20:44:06 GMT-0700",
"expr":"[sling:resourceType=dam/components/scene7/dynamicmedia]",
"sling":"resourceType":"slingPipes/find"
},
"updateProperty":{
"jcr":"primaryType":"nt:unstructured",
"sling":"resourceType":"slingPipes/write",
"conf":{
"jcr":"primaryType":"nt:unstructured",
s7ViewerPreset:"${findNodes.s7ViewerPreset.replaceAll("/etc/dam/presets","/conf/global/settings/dam/dm/presets")}"
}
}
}
}

Good luck!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in Adobe Tech Blog

News, updates, and thoughts related to Adobe, developers, and technology.

Written by Kaushal Mall

Engineering Manager @ Adobe, AEM Assets as a Cloud Service

No responses yet

Write a response