AEM Nested Multifield Sling Model
I'm attempting to write a multifield navigation component in AEM following this guide here:
I have it working fairly well using interfaces, but when I try to implement a class based approach AEM no longer seems to pick up my primaryLinks / secondaryLinks / tertiaryLinks content. From what I can tell in the AEM documentation here: https://sling.apache.org/documentation/bundles/models.html#collections it seems like it should be possible for the Sling Model to pick up the List just by using @586265. Am I missing something here? I've also attached an image of the content I'm attempting to work with along w/ code below.
CRX: 
Model w/ Interfaces (works) :
@Model(
adaptables = {Resource.class},
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public interface Navigation {
@Inject
List<PrimaryLink> getPrimaryLinks();
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
interface PrimaryLink {
@Inject
String getName();
@Inject
List<SecondaryLink> getSecondaryLinks();
}
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
interface SecondaryLink {
@Inject
String getName();
@Inject
List<TertiaryLink> getTertiaryLinks();
}
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
interface TertiaryLink {
@Inject
String getName();
}
}HTL:
<sly data-sly-use.model="com.havertys.core.models.Navigation"/>
<sly data-sly-test.empty="${!model.primaryLinks}" />
<div data-sly-test="${wcmmode.edit && empty}" class="cq-placeholder" data-emptytext="${component.title}"></div>
<sly data-sly-test="${!empty}">
<div>
<ul data-sly-list.primaryLink="${model.primaryLinks}">
<li>${primaryLink.name}
<ul data-sly-list.secondaryLink="${primaryLink.secondaryLinks}">
<li>
<b>Secondary:</b> ${secondaryLink.name} <br/>
<ul data-sly-list.tertiaryLink="${secondaryLink.tertiaryLinks}">
<li>
<b>Tertiary: </b> ${tertiaryLink.name}
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</sly>Class Based Model (Doesn't Work). I've also tried adding getters but that fails as well.
@Model(
adaptables = {Resource.class},
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class Navigation {
@Inject
private List<PrimaryLink> primaryLinks;
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class PrimaryLink {
@Inject
private String name;
@Inject
private List<SecondaryLink> secondaryLinks;
}
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class SecondaryLink {
@Inject
private String name;
@Inject
private List<TertiaryLink> tertiaryLinks;
}
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class TertiaryLink {
@Inject
private String name;
}
}Dialog:
<?xml version="1.0" encoding="UTF-8"?>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Copyright 2021 Adobe
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Navigation"
sling:resourceType="cq/gui/components/authoring/dialog"
extraClientlibs="[core.wcm.components.navigation.v1.editor]"
helpPath="https://www.adobe.com/go/aem_cmp_navigation_v2"
trackingFeature="core-components:navigation:v2">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs"
maximized="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<navigationLinksTab
jcr:primaryType="nt:unstructured"
jcr:title="Navigation Links"
sling:resourceType="granite/ui/components/coral/foundation/container"
margin="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<primaryLinks
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldLabel="Primary Links">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./primaryLinks">
<items jcr:primaryType="nt:unstructured">
<name
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
emptyText="Name"
fieldLabel="Primary Link Name"
name="./name"/>
<secondaryLinks
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldLabel="Secondary Links">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./secondaryLinks">
<items jcr:primaryType="nt:unstructured">
<name
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
emptyText="Name"
fieldLabel="Secondary Link Name"
name="./name"/>
<tertiaryLinks
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldLabel="Tertiary Links">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./tertiaryLinks">
<items jcr:primaryType="nt:unstructured">
<name
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
emptyText="Name"
fieldLabel="Tertiary Link Name"
name="./name"/>
</items>
</field>
</tertiaryLinks>
</items>
</field>
</secondaryLinks>
</items>
</field>
</primaryLinks>
</items>
</navigationLinksTab>
<promotionTab
jcr:primaryType="nt:unstructured"
jcr:title="Products"
sling:resourceType="granite/ui/components/coral/foundation/container"
margin="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<columns
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
margin="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<accessibilityLabel
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Value of an aria-label attribute for the navigation. Should be added if there is more than one navigation on the page."
fieldLabel="Label"
name="./accessibilityLabel"
value=""/>
</items>
</column>
</items>
</columns>
</items>
</promotionTab>
</items>
</tabs>
</items>
</content>
</jcr:root>