Robert Munteanu
Robert Munteanu

Reputation: 68278

How do I include a resource in a Sightly template only if it exists?

I would like to use data-sly-resource to include a resource, but only if it exists, e.g.

<div class="pull-right" data-sly-resource="/content/blog/stats"></div>

If the resource does not exist the script execution fails with the following error message: Cannot find servlet to handle resource /content/blog/stats . From the Request Progress listing I can see that it's a SyntheticResource:

TIMER_START{resolveServlet(SyntheticResource, type=null, path=/content/blog/stats)}

How can I include the resource conditionally, only if it exists?

Upvotes: 6

Views: 7139

Answers (3)

ccpizza
ccpizza

Reputation: 31686

If the resource you need to include (e.g. stats) is a child of the current resource, then this might work:

<div data-sly-test="${resource['stats/jcr:primaryType']}"
    class="pull-right" 
    data-sly-resource="stats"></div>

Upvotes: 2

Radu Cotescu
Radu Cotescu

Reputation: 534

In this case the best solution would be to allow your redis/stats component to correctly handle the situation when a Resource it's supposed to render is a SyntheticResource or, more generally, doesn't provide any properties.

Therefore the calling Sightly snippet should be:

<div class="pull-right" data-sly-resource="${'/content/blog/stats' @ resourceType='redis/stats'}"></div>

This forces the rendering to be made by your redis/stats component, even if the /content/blog/stats resource doesn't exist (well, Sling will return a SyntheticResource, like you mentioned).

In your redis/stats component you could then try this safeguard:

<div class="blog-stats" data-sly-test="${properties}">
<!--/* This whole block will only be rendered if properties is not empty */-->
</div>

which would render the div.blog-stats only if the properties map was not empty [0].

[0] - https://github.com/Adobe-Marketing-Cloud/sightly-spec/blob/1.1/SPECIFICATION.md#225-test

Upvotes: 4

Robert Munteanu
Robert Munteanu

Reputation: 68278

Implement a use script which tests for the existence of the resource:

stats.js:

use(function () {

    var hasStats = false;
    var stats = resource.getResourceResolver().getResource('/content/blog/stats');
    if ( stats != null && stats.getResourceType() == "redis/stats" ) {
        hasStats = true;
    } 

    return {
        hasStats: hasStats
    }
});

page.html:

<sly data-sly-use.stats="stats.js"/>

<div data-sly-test="${stats.hasStats}" class="pull-right" data-sly-resource="/content/blog/stats"></div>

This has the disadvantage of requiring a use script, hopefully there is a simpler way.

Upvotes: 1

Related Questions