I'm new to AEM, so any advice is appreciated.
Let's say I've something like this:
<div class="big-item" data-sly-list="${features.list}">
<sly data-sly-test="${ itemList.first || itemList.count == 5 || itemList.count == 9 || itemList.count == 13 || itemList.count == 17 }">
<div class="small-item-wrapper>
<div class="additional-div">
</sly>
<div class="small-item">
<div>${item.somecontent}</div>
</div>
<sly data-sly-test="${ itemList.last || itemList.count == "4 || itemList.count == 8 || itemList.count == 12 || itemList.count == 16 }">
</div>
</div>
</sly>
</div>
Basically, what I'm trying to do is to wrap every 4 items in a separate container.
For now, the closing tag isn't rendered or rather is closed only after the last iteration.
Is such an html-templating approach doable in AEM? Can I do this purely in htl? Currently, this does not work for me, I suppose there's some automation going on which I'm not aware of.
How can I do this?
PS. When the structure is simple (no nested divs) seems to be working, when subdivs are added it starts to break.
No, that's not allowed as the HTL script should be a valid HTML (hence no unfinished/conditional tags). There are a few workaround though. Let's assume your items look like (JS use-object that can be tested with HTL REPL):
use(function () {
return {
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
};
});
You could then render them with this HTL script:
<div class="big-item" data-sly-use.logic="logic.js">
<div class="small-item-wrapper" data-sly-test="${logic.list.length > 0}">
<div class="additional-div">
<div class="small-item" data-sly-repeat="${logic.list @ begin=0, end=3}">
<div>${item}</div>
</div>
</div>
</div>
<div class="small-item-wrapper" data-sly-test="${logic.list.length > 4}">
<div class="additional-div">
<div class="small-item" data-sly-repeat="${logic.list @ begin=4, end=7}">
<div>${item}</div>
</div>
</div>
</div>
<div class="small-item-wrapper" data-sly-test="${logic.list.length > 8}">
<div class="additional-div">
<div class="small-item" data-sly-repeat="${logic.list @ begin=8, end=11}">
<div>${item}</div>
</div>
</div>
</div>
<div class="small-item-wrapper" data-sly-test="${logic.list.length > 12}">
<div class="additional-div">
<div class="small-item" data-sly-repeat="${logic.list @ begin=12, end=15}">
<div>${item}</div>
</div>
</div>
</div>
</div>
It's ugly and hardcoded up to 16 items but should work.
If you can "massage" the data ahead of time you could prepare a set of [begin
, end
] markers and make the HTL script nicer. Here's the use-object:
use(function () {
let list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17];
let markers = [];
for (let i=0; i<list.length; i++) {
if (i % 4 === 0) {
markers.push([i, i+3]);
}
}
return {
markers: markers,
list: list
};
});
and corresponding HTL script:
<div class="big-item">
<div class="small-item-wrapper" data-sly-repeat.marker="${logic.markers}">
<div class="additional-div">
<div class="small-item" data-sly-repeat="${logic.list @ begin=marker[0], end=marker[1]}">
<div>${item}</div>
</div>
</div>
</div>
</div>