AEM 6.4 - 如何使用 Sling 模型从设计对话框中读取多字段?

AEM 6.4 - How to read multifield from design dialog using Sling model?

我创建了一个带有设计对话框和策略的组件。我可以阅读设计对话框的基本属性,但对如何处理多字段感到困惑。

设计对话框(检查 headerPrimaryLinks)

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="nt:unstructured"
    jcr:title="Header"
    sling:resourceType="cq/gui/components/authoring/dialog">
    <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">
                    <properties
                        jcr:primaryType="nt:unstructured"
                        jcr:title="Main"
                        sling:resourceType="granite/ui/components/coral/foundation/container"
                        margin="{Boolean}true">
                        <items jcr:primaryType="nt:unstructured">
                            <heading
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                fieldLabel="Heading"
                                name="./heading"/>
                            <logoAltText
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                fieldLabel="Logo Alt Text"
                                name="./alttext"/>
                        </items>
                    </properties>
                    <!-- <styletab
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/coral/foundation/include"
                        path="/mnt/overlay/cq/gui/components/authoring/dialog/style/tab_design/styletab"/> -->
                    <primaryLinks
                        jcr:primaryType="nt:unstructured"
                        jcr:title="Primary Links"
                        sling:resourceType="granite/ui/components/coral/foundation/container"
                        margin="{Boolean}true">
                        <items jcr:primaryType="nt:unstructured">
                            <link
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
                                composite="{Boolean}true"
                                fieldDescription="Click '+' to add a new link">
                                <field
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/coral/foundation/form/fieldset"
                                    name="./headerPrimaryLinks">
                                    <items jcr:primaryType="nt:unstructured">
                                        <column
                                            jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/coral/foundation/container">
                                            <items jcr:primaryType="nt:unstructured">
                                                <title
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                    fieldLabel="Title"
                                                    name="./title"/>
                                                <linkURL
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/pathbrowser"
                                                    fieldLabel="Link to"
                                                    name="./linkURL"
                                                    rootPath="/content"/>
                                            </items>
                                        </column>
                                    </items>
                                </field>
                            </link>
                        </items>
                    </primaryLinks>
                </items>
            </tabs>
        </items>
    </content>
</jcr:root>

Header.java class

import javax.annotation.PostConstruct;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.wcm.api.policies.ContentPolicy;
import com.day.cq.wcm.api.policies.ContentPolicyManager;

@Model(adaptables = Resource.class)
public class Header {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @SlingObject
    private ResourceResolver resourceResolver;

    @Self
    protected Resource resource;

    private String heading,
                   altText;

    @PostConstruct
    protected void init() {
        ContentPolicyManager policyManager = resourceResolver.adaptTo(ContentPolicyManager.class);

        if (policyManager != null) {
            ContentPolicy contentPolicy = policyManager.getPolicy(resource);

            if (contentPolicy != null) {
                ValueMap properties = contentPolicy.getProperties();

                // I can read these fine but how do I read a multifield?
                heading = (String) properties.get("heading");
                altText = (String) properties.get("alttext");
            }
        }
    }

    /**
    * Returns heading from design dialog.
    * 
    * @return heading
    */
    public String getHeading() {
        return heading;
    }

    /**
    * Returns alttext (logo alt text) from design dialog.
    * 
    * @return altText
    */
    public String getAltText() {
        return altText;
    }
}

在组件中,我可以读取如下字符串:

<sly data-sly-use.header="com.uchealth.aem.core.models.Header">
    ${header.heading}
</sly>

或者只是

${currentStyle.heading}

这是它在 CRX 中的样子:

header
-  policy_1547171225060
    - headerPrimaryLinks
      - item0
      - item1
      - item2
    - headerSecondaryLinks
      - item0
      - item1
      - item2

如何读取多字段以在我的 HTL 中使用 data-sly-list?

我没有测试过这个,所以我不确定它是否 100% 有效。 首先,您需要一个 SlingModel 来表示多字段项目:

@Model(adaptables = Resource.class)
public class HeaderPrimaryLink {

    @Inject
    private Resource resource;

    @Inject
    @Optional
    private String title;

    @Inject
    @Optional
    private String linkURL;

    public String getTitle() {
        return title;
    }

    public String getLinkURL() {
        return linkURL;
    }
}

然后,在您的 "Header" 模型中,您可以得到一个 "HeaderPrimaryLink" 模型列表,其中将包含填充在多字段中的所有项目:

...
    private String heading,
               altText;

    private List<HeaderPrimaryLink> links;

    @PostConstruct
...

我不确定多字段是如何存储在策略节点下的(如果可以 post CRX 中的节点图像会有所帮助),但假设多字段存储为节点策略资源,我会尝试获取该节点并填充列表(类似这样):

    Resource multifieldResource = resourceResolver.getResource(contentPolicy.getPath() + "/headerPrimaryLinks");
    if (multifieldResource != null) {
        for (Resource currentResource : multifieldResource.getChildren()) {
            links.add(currentResource.adaptTo(HeaderPrimaryLink.class));
        }
    }

然后在 HTML:

<sly data-sly-use.header="com.uchealth.aem.core.models.Header">
    <ul data-sly-list="${header.links}">
        <li>
           <a target="_blank" href="${item.linkURL}">${item.title}</a>
        </li>
    </ul>
</sly>

希望对您有所帮助。