Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AEM 6.0: Additional parameters when using data-sly-resource?

Tags:

aem

sightly

I am trying to implement something which I hope is relatively straight forward... I have one component (lets call it the wrapper component) which contains another component (lets call it the inner component) inside it via the data-sly-resource tag:

<div data-sly-resource="${ 'inner' @ resourceType='/projectname/components/inner' }"></div>

I would like to pass in some additional parameters with this tag, specifically a parameter that can be picked up by sightly in the inner component template? I am trying to specify whether the inner templates outer html tag is unwrapped based on a parameter being passed in when the component is called via data-sly-resource.

After experimenting and perusing the sightly documentation, I can't find a way of achieving this.

Does anyone know if this is possible?

Many thanks,

Dave

like image 369
David Woollard Avatar asked Aug 20 '14 12:08

David Woollard


2 Answers

You can use the Use-API to write and read request attributes if the alternatives proposed here don't work for you.

A quick example of two components where the outer component sets attributes that are then displayed by the inner component:

/apps/siteName/components/
    outer/ [cq:Component]
        outer.html
    inner/ [cq:Component]
        inner.html
    utils/ [nt:folder]
        setAttributes.js
        getAttributes.js
/content/outer/ [sling:resourceType=siteName/components/outer]
    inner [sling:resourceType=siteName/components/inner]

/apps/siteName/components/outer/outer.html:

<h1>Outer</h1>
<div data-sly-use="${'../utils/setAttributes.js' @ foo = 1, bar = 2}"
     data-sly-resource="inner"></div>

/apps/siteName/components/inner/inner.html:

<h1>Inner</h1>
<dl data-sly-use.attrs="${'../utils/getAttributes.js' @ names = ['foo', 'bar']}"
    data-sly-list="${attrs}">
    <dt>${item}</dt> <dd>${attrs[item]}</dd>
</dl>

/apps/siteName/components/utils/setAttributes.js:

use(function () {
    var i;
    for (i in this) {
        request.setAttribute(i, this[i]);
    }
});

/apps/siteName/components/utils/getAttributes.js:

use(function () {
    var o = {}, i, l, name;
    for (i = 0, l = this.names.length; i < l; i += 1) {
        name = this.names[i];
        o[name] = request.getAttribute(name);
    }
    return o;
});

Resulting output when accessing /content/outer.html:

<h1>Outer</h1>
<div>
    <h1>Inner</h1>
    <dl>
        <dt>bar</dt> <dd>2</dd>
        <dt>foo</dt> <dd>1</dd>
    </dl>
</div>

As commented by @AlasdairMcLeay, this proposed solution has an issue in case the inner component is included multiple times on the request: the subsequent instances of the component would still see the attributes set initially.

This could be solved by removing the attributes at the moment when they are accessed (in getAttributes.js). But this would then again be a problem in case the inner component is split into multiple Sightly (or JSP) files that all need access to these attributes, because the first file that accesses the request attributes would also remove them.

This could be further worked-around with a flag telling wether the attributes should be removed or not when accessing them... But it also shows why using request attributes is not a good pattern, as it basically consists in using global variables as a way to communicate among components. So consider this as a work-around if the other two solutions proposed here are not an option.

like image 116
Gabriel Walt Avatar answered Oct 14 '22 20:10

Gabriel Walt


There is a newer feature that request-attributes can be set on data-sly-include and data-sly-resource :

<sly data-sly-include="${ 'something.html' @ requestAttributes=amapofattributes}" />

Unfortunately it doesn't seem to be possible to construct a Map with HTL (=Sightly) expressions, and I don't see a way to read a request attribute from HTL, so you still need some Java/Js code for that.

like image 39
Hans-Peter Störr Avatar answered Oct 14 '22 18:10

Hans-Peter Störr