Is there anything in CQ API to allow you to create a node from a cq:component?

StackOverflow https://stackoverflow.com/questions/23482515

  •  16-07-2023
  •  | 
  •  

質問

I'm curious about whether or not there is something in the CQ API that will allow me to create a node based on a cq:component, much like what would happen when an author adds a component to a parsys.

Because I needed to get the piece done, I went ahead and did it manually. I've included this solution to see if someone can go "oh man there's this .* method you can use to do exactly that".

This is what I'm doing:

public static Node createFromComponent(Node dstParent, Node srcComponent, String targetName) {
    Node newNode = null;

    try {
        //if there is a template use it
        if (srcComponent.hasNode("cq:template")) {
            newNode = JcrUtil.copy(srcComponent.getNode("cq:template"), dstParent, targetName);
        }
        else {
            newNode = dstParent.addNode(targetName);
        }

        //set the resourceType to the path of the component sent over
        newNode.setProperty("sling:resourceType", srcComponent.getPath());

        newNode.getSession().save();
    }
    catch(Exception e) {
        LOGGER.error("Error creating node from component: ", e);
    }

    return newNode;
}

It's pretty straight forward. I was looking at the JcrUtil Class, but I don' t think it has what I'm looking for.

役に立ちましたか?

解決

Unfortunately, there isn't a built-in method that:

  1. copies contents of the cq:template node or
  2. creates a new node,
  3. sets a sling:resourceType property to the node.

When you drag the component from sidekick to parsys, your browser sends a HTTP POST request to the Sling. If the target component contains cq:template subnode, this HTTP request will contain an additional property:

./@CopyFrom:/apps/my/component/cq:template

which takes care of setting default values. Because you want to do the same thing via API rather than HTTP request, you need a custom method.

他のヒント

You could go a level higher & use the Sling API rather than JCR. If you adapt the cq:template node to a ValueMap & then pass it to the ResourceResolver.create() method…

E.g.

<%  
    Resource templateAsResource = resourceResolver.resolve("/path/to/cq:template");
    ValueMap templateProperties = templateAsResource.adaptTo(ValueMap.class);
    resourceResolver.create(parentResource, "newResource", templateProperties);
    resourceResolver.commit();
%>

Have given this a quick test locally — it works in Author mode when authenticated. (If you're running it in a Publish instance or as a non-admin user, you may need a few extra lines to ensure you have permissions both to create the node but also to read the cq:template file under /apps)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top