0

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

ltoodee
  • 51
  • 1
  • 5

1 Answers1

3

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.

  • resource.properties[property]; works! The first solution still doesn't work. Thank you for the other links, I don't think I can use HierarchyNodeInheritanceValueMap API because Im using the Javascript HTL Use API. – ltoodee Aug 07 '17 at 07:42
  • Just out of curiosity, is adaptTo method returning null again or is it a different error. The one possible error which can appear here is related to commented line for getting value, Node API provides getProperty method and it is throwing errors instead of Sling nulls when a property is not found. Regarding HierarchyNodeInheritanceValueMap server-side JS is compiled to Java with Rhino anyway and all the objects used are actually Java objects. It should be also able to import objects from different packages, some of them are already imported. I updated my answer with some more examples. – Kamil Ciecierski Aug 07 '17 at 19:07
  • @KamilCiecierski this is very helpful! where would I look to find out what properties and methods are available to me within the HTL Javascript Use-API? – Damon Jun 29 '18 at 15:03