0
votes

I have a footer element which needs to be shared. My plan is to set up the footer on the parent/home page but allow child pages to overwrite those properties.

I first look on the current component for the property (pretty standard), after that I get the path to the parent page to look for the property on the component with the same name.

function getProperty(property, currentPage) {
    var val = null,
        page = currentPage,
        rootPage = page.getAbsoluteParent(2);

    var curNode = currentNode.getPath(),
        nodeStrIdx = curNode.indexOf("jcr:content"),
        nodeStr = curNode.substr(nodeStrIdx + 12);  // Remove 'jcr:content/' too

    while(val == null) {

        // If we've gone higher than the home page, return
        if(page.getDepth() < 3) {
            break;
        }

        // Get the same node on this page
        var resource = page.getContentResource(nodeStr);

        if(resource != null) {
            var node = resource.adaptTo(Node.class);  // *** This is null ***

            // val = node.get(property);
        }

        // Get the parent page
        page = page.getParent();
    }

    return val;
}

I've seen that you can change the type of the content resource to a node which should allow me to get the same property but the resource.adaptTo(Node.class) is returning null.

In case it's not clear, resource is an absolute path to the node I want to pull the property from e.g. /content/jdf/en/resources/challenge-cards/jcr:content/footer/follow-us

1

1 Answers

3
votes

Assuming you are using Javascript HTL Use API, you need to use fully qualified name for Java class, like this:

var node = resource.adaptTo(Packages.javax.jcr.Node);

Then you can retrieve your value in this way:

if (node.hasProperty(property)) {
    val = node.getProperty(property).getString();
}

You need to use hasProperty method per Node API as getProperty throws PathNotFoundException when a property is missing. You also need to be careful with granite.resource object from examples - it is not the same Resource object and it does not have adaptTo method. To get to the original resource of the component you need to take nativeResource property:

var node = granite.resource.nativeResource.adaptTo(Packages.javax.jcr.Node);

However, there also should be a faster way to get property from the resource in JS:

val = resource.properties[property];

As this is a quite common case to develop components properties inheritance, you can also consider some ready-to-use solutions like HierarchyNodeInheritanceValueMap API or Inheritance Paragraph System (iparsys) in your implementation design.

As this JS is server-side compiled with Mozilla Rhino, all these objects and methods used here are Java objects and methods so that you should be also able to use HierarchyNodeInheritanceValueMap in this way:

//importClass(Packages.com.day.cq.commons.inherit.HierarchyNodeInheritanceValueMap);
//this import might be needed but not necessarily

var props = new HierarchyNodeInheritanceValueMap(granite.resource.nativeResource);
val = props.getInherited(property, Packages.java.lang.String);

It will then return to val the property value for the current resource, or, if empty, the property value of the resource at the same position on the parent page, or if empty etc. These two lines should do all the magic then.