AEM HTL Multifield Iteration Issue - Dialog seems correct but no rendering | Community
Skip to main content
August 7, 2025
Question

AEM HTL Multifield Iteration Issue - Dialog seems correct but no rendering

  • August 7, 2025
  • 2 replies
  • 528 views

Hello everyone,

I'm working on an AEM component and have configured a multifield dialog. My goal is to iterate over the items added in this multifield using HTL.

The data appears to be saving correctly in CRXDE Lite under the component's node in a structure like /path/to/component/tiles/item0, /path/to/component/tiles/item1, etc., with properties like itemTitle on each itemX node.

Here is the relevant part of my dialog XML:

 

 

<tiles jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/multifield" composite="{Boolean}true" fieldLabel="Tiles" fieldDescription="Click 'Add field' to add the details for a new tile."> <field jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/fieldset" name="./tiles"> <layout jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/container"> <items jcr:primaryType="nt:unstructured"> <title jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/textfield" fieldLabel="Title" name="itemTitle"/> <!-- Other fields would go here --> </items> </column> </items> </field> </tiles>

However, I'm unable to get anything to render in my HTL file. I've tried various approaches, but nothing seems to work.

Can someone please provide the correct HTL syntax to iterate over these multifield items? I'm trying to access the itemTitle property for each one.

I'd prefer a solution that doesn't require a Sling Model like using ${properties}

Thank you in advance for any help!

 

2 replies

SantoshSai
Community Advisor
Community Advisor
August 8, 2025

Hi @julioro,

Since you've used composite="{Boolean}true" in your multifield and saved each item as a child node (eg. item0, item1, ...), accessing it purely via HTL without a Sling Model becomes limited, but it's still possible using resource.getChildren.

Here’s how you can iterate over the child nodes of the multifield path (tiles) in your component's HTML file:

<ul data-sly-list.item="${resource.getChild('tiles').listChildren}"> <li>${item.getValueMap['itemTitle']}</li> </ul>

 
However, as a best practice - my recommendation would be to go with Sling Model, here’s why Sling Models are preferred:

  • Cleaner HTL: Business logic (like sorting, filtering, transforming) can be handled in Java.

  • Better error handling: You can validate presence of fields and fallback defaults.

  • Reusable data access: A Sling Model can be reused across components or templates.

  • Unit testability: Logic in Sling Models can be unit tested, HTL can't.

Example (just for reference):

@Model(adaptables = Resource.class)
public class TileComponent {
    @ValueMapValue
    private String itemTitle;
    
    // Getters...
}

Then in HTL:

<ul data-sly-list.item="${tileModel.tiles}">
  <li>${item.itemTitle}</li>
</ul>

 

Santosh Sai
JulioRoAuthor
August 8, 2025

This isn’t working

<ul data-sly-list.item="${resource.getChild('tiles').listChildren}">
    <li>${item.getValueMap['itemTitle']}</li>
</ul>

 

I’m getting an error.

org.apache.sling.scripting.sightly.SightlyException: org.apache.sling.api.SlingException: Cannot get DefaultSlingScript: org.apache.sling.scripting.sightly.SightlyException: org.apache.sling.api.scripting.ScriptEvaluationException: ${resource.getChild('tiles').listChildren}: mismatched input '(' expecting {'}', '@'} in /apps/project/components/contenttilegrid/contenttilegrid.html at line number 39 at column number 64


Here’s the content from CRXDE.

 

August 13, 2025

Hi @julioro  ,

Could you try below
Check if ${resource.getChild('tiles')} is not null
${resource.getChild('tiles').children}
<li>${item.valueMap.itemTitle}</li>