如何仅在 Sightly 模板中包含存在的资源?

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

我想使用 data-sly-resource 来包含资源,但前提是它存在,例如

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

如果资源不存在,脚本执行将失败并显示以下错误消息:找不到 servlet 来处理资源 /content/blog/stats。从 Request Progress 列表中我可以看到它是 SyntheticResource:

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

我怎样才能有条件地包含资源,只有当它存在时?

执行测试资源是否存在的使用脚本:

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>

缺点是需要使用脚本,希望有更简单的方法。

在这种情况下,最好的解决方案是让您的 redis/stats 组件正确处理应该呈现的 ResourceSyntheticResource 的情况,或者更一般地说,不提供任何属性。

因此调用 Sightly 代码段应该是:

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

这会强制由您的 redis/stats 组件进行渲染,即使 /content/blog/stats 资源不存在(好吧,Sling 会 return 一个 SyntheticResource ,就像你提到的那样)。

在您的 redis/stats 组件中,您可以尝试此保护措施:

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

仅当属性映射不为空 [0] 时才会呈现 div.blog-stats

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

如果您需要包含的资源(例如stats)是当前资源的子资源,那么这可能有效:

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