Hi, after running Best Practices Analyzer tool, we have found lot of issues with " is missing mandatory 'jcr:content' child node." in some of our folders. how to fix this issue? i know a groovy script can be used, but any other ways?
with groovy script can we insert an empty jcr:content node to fix the issue? if yes, any code snipped to help achieve this?
thank
I went through https://github.com/hashimkhan786/aem-groovy-scripts , but couldn't find any script to help in the direction iam looking for
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
Hey @ASP_Corp ,
Yes, a Groovy script can be used to fix this issue efficiently. Below is a Groovy script that recursively scans and adds the missing jcr:content nodes to cq:Page under a given path. Similarly, you can update for other node primary types.
import com.day.cq.commons.jcr.JcrUtil
import javax.jcr.*
def session = resourceResolver.adaptTo(Session)
def rootPath = "/content/we-retail/it" // Change this to the desired root path
def processNode(node) {
if (!node.hasNode("jcr:content")) {
def contentNode = node.addNode("jcr:content", "nt:unstructured")
contentNode.setProperty("createdBy", session.getUserID())
contentNode.setProperty("createdDate", Calendar.getInstance())
println "Added missing jcr:content node at: ${node.path}"
}
}
// Recursively scan folders and add missing jcr:content nodes
def scanAndFixMissingContentNodes(node) {
if (node.isNodeType("cq:Page")) { //Use other condition to handle the allowed primanryType to add child jcr:content
processNode(node)
}
def nodeIterator = node.getNodes()
while (nodeIterator.hasNext()) {
scanAndFixMissingContentNodes(nodeIterator.nextNode())
}
}
def rootNode = session.getNode(rootPath)
scanAndFixMissingContentNodes(rootNode)
session.save()
println "Completed processing for missing jcr:content nodes."
Regards,
Hey @ASP_Corp ,
Yes, a Groovy script can be used to fix this issue efficiently. Below is a Groovy script that recursively scans and adds the missing jcr:content nodes to cq:Page under a given path. Similarly, you can update for other node primary types.
import com.day.cq.commons.jcr.JcrUtil
import javax.jcr.*
def session = resourceResolver.adaptTo(Session)
def rootPath = "/content/we-retail/it" // Change this to the desired root path
def processNode(node) {
if (!node.hasNode("jcr:content")) {
def contentNode = node.addNode("jcr:content", "nt:unstructured")
contentNode.setProperty("createdBy", session.getUserID())
contentNode.setProperty("createdDate", Calendar.getInstance())
println "Added missing jcr:content node at: ${node.path}"
}
}
// Recursively scan folders and add missing jcr:content nodes
def scanAndFixMissingContentNodes(node) {
if (node.isNodeType("cq:Page")) { //Use other condition to handle the allowed primanryType to add child jcr:content
processNode(node)
}
def nodeIterator = node.getNodes()
while (nodeIterator.hasNext()) {
scanAndFixMissingContentNodes(nodeIterator.nextNode())
}
}
def rootNode = session.getNode(rootPath)
scanAndFixMissingContentNodes(rootNode)
session.save()
println "Completed processing for missing jcr:content nodes."
Regards,
@ASP_Corp by any chance folders are indexed and if jcr:content nodes are missing in multiple paths where each path contains huge data then better to go with (SQL2 query + groovy script) instead of iterating the nodes in groovy script . To avoid putting a check for each node and checking if is a folder and then folder has node jcr:content, you can directly write a SQL2 query which will directly give you the folders which doesn't have jcr:content nodes. Sample code is
import javax.jcr.Session
import javax.jcr.query.Query
import javax.jcr.query.QueryManager
import javax.jcr.query.QueryResult
def session = resourceResolver.adaptTo(Session.class)//get resolver first and then session
def queryManager = session.workspace.queryManager// get query manager
def folderPath = "/path/to/your/folder" // Replace with your folder path
// SQL2 query to find folders missing jcr:content nodes
def sql2Query = """
SELECT * FROM [nt:folder] AS folder
WHERE ISDESCENDANTNODE(folder, '${folderPath}')
AND NOT EXISTS (SELECT * FROM [nt:base] AS content WHERE ISCHILDNODE(content, folder) AND NAME(content) = 'jcr:content')
"""
//You can try below query in above sql2Query variable:
SELECT * FROM [nt:folder] AS folder
WHERE ISDESCENDANTNODE(folder, '/path/to/your/folder')
AND folder.[jcr:content/jcr:primaryType] IS NULL
def query = queryManager.createQuery(sql2Query, Query.JCR_SQL2)
def result = query.execute()
result.nodes.each { node ->
def folderNode = node
if (!folderNode.hasNode("jcr:content")) {
def jcrContentNode = folderNode.addNode("jcr:content", "nt:unstructured")
jcrContentNode.setProperty("jcr:primaryType", "nt:unstructured")
session.save()
println "Added jcr:content node to ${folderNode.path}"
}
}
Thanks
Ramesh
Hi Ramesh,
thanks for the help. the query
SELECT * FROM [nt:folder] AS folder WHERE ISDESCENDANTNODE(folder, '/path/to/your/folder') AND folder.[jcr:content/jcr:primaryType] IS NULL
is giving out a lot of results and along with the folders it is giving the renditions too. for e.g it gives /content/dam/_folder and also /content/dam/_CSS/_OOTB/AudioCaptionsButton_sprite.png/jcr:content/renditions ..etc...we are expecting 345 results from the BPA but the query is giving around 60000 results
@ASP_Corp Did you find the suggestion helpful? Please let us know if you need more information. If a response worked, kindly mark it as correct for posterity; alternatively, if you found a solution yourself, we’d appreciate it if you could share it with the community. Thank you!
Views
Replies
Total Likes
@ASP_Corp Did you find the suggestions helpful? Please let us know if you need more information. If a response worked, kindly mark it as correct for posterity; alternatively, if you found a solution yourself, we’d appreciate it if you could share it with the community. Thank you!
Views
Replies
Total Likes