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>
希望对您有所帮助。
我创建了一个带有设计对话框和策略的组件。我可以阅读设计对话框的基本属性,但对如何处理多字段感到困惑。
设计对话框(检查 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>
希望对您有所帮助。