如何继承 AEM 6.2 中的页面属性?
How can I inherit page properties in AEM 6.2?
在我们的 AEM 6.2 项目中,我 运行 需要在一个页面(我们称之为主页)中配置导航的场景,所有其他页面都可以使用主页导航配置或使用自己的导航配置值。
我决定使用live copy,因为克隆页面可以随时取消链接属性并使用它们自己的值。但是这种方法有两个问题:
- 用户必须通过编辑他们的 jcr: content/sling:resourceType 和 jcr: content/cq: template 来设置克隆页面的模板,因为所有页面都使用了导航,而我们的网站使用了大约 5+模板。
Live Copy 不允许克隆页面是源页面的子页面。但是我被要求制作这样的网络结构:
Home
|_ Page 1
|_ Page 1.1
|_ Page 2
|_ Page 3
Live Copy可能不适合这种情况,我们改为使用HTL ${inheritedPageProperties}
,这解决了模板和结构问题,但又产生了两个新问题:
子页面的 属性 配置对话框中的继承属性将为空白(因为它们未通过 ${inheritedPageProperties}
设置和调用)
如果用户更改 "Page 1" 页面中的属性,"Page 1.1"(和页面 1.1.1 等...)将使用这些值(因为 ${inheritedPageProperties}
搜索上层节点以获取值)。
我们客户想要的是:
- 所有页面只能从主页或自己的页面使用导航设置(默认使用主页)。
- 如果使用主页属性,这些值必须显示在其配置对话框中。
- 尽量避免使用 CRXDE Lite 中的配置模板
- 网站必须有父子结构
我怎样才能达到这些要求?
您可以通过简单的 Sling Model and Sling's CompositeValueMap
CompositeValueMap 文档状态:
An implementation of the ValueMap based on two ValueMaps: - One containing the properties - Another one containing the defaults to use in case the properties map does not contain the values. In case you would like to avoid duplicating properties on multiple resources, you can use a CompositeValueMap to get a concatenated map of properties.
我们可以通过提供后代的值映射(当前页面的)然后找到正确的祖先并将其属性值映射作为默认值来使用它。
for the purposes of this question, I always assume that 2rd descendant from root is always the ancestor (you can find your ancestor according to your requirnments)
package com.sample.helpers;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.CompositeValueMap;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.apache.sling.models.annotations.injectorspecific.Self;
import javax.annotation.PostConstruct;
@Model(adaptables = Resource.class)
public class CustomInheritedPageProperties
{
ValueMap inheritedProperties;
@Self
Resource currentResource;
@OSGiService
PageManager pageManager;
@PostConstruct
protected void init() {
// get the current page, or the "descendant"
Page descendant = pageManager.getContainingPage(currentResource);
/* You have to add your custom logic to get the ancestor page.
* for this question's purposes, I'm always assuming it's the 3rd decendant of root
* more here: https://helpx.adobe.com/experience-manager/6-2/sites/developing/using/reference-materials/javadoc/com/day/cq/wcm/api/Page.html#getParent(int)
*/
Page ancestor = descendant.getParent(2);
// create a CompositeValueMap where the properties are descendant's and the defaults are ancestor's
inheritedProperties = new CompositeValueMap(descendant.getProperties(), ancestor.getProperties());
}
public ValueMap getInheritedProperties()
{
return inheritedProperties;
}
}
现在您可以按如下方式使用它
<sly data-sly-use.propHelper="com.sample.helpers.CustomInheritedPageProperties">>/sly>
<!--/* someProp here refers to the property you wish to get (inherited, of course)*/-->
<h1>propHelper.inheritedProperties.someProp</h1>
在我们的 AEM 6.2 项目中,我 运行 需要在一个页面(我们称之为主页)中配置导航的场景,所有其他页面都可以使用主页导航配置或使用自己的导航配置值。
我决定使用live copy,因为克隆页面可以随时取消链接属性并使用它们自己的值。但是这种方法有两个问题:
- 用户必须通过编辑他们的 jcr: content/sling:resourceType 和 jcr: content/cq: template 来设置克隆页面的模板,因为所有页面都使用了导航,而我们的网站使用了大约 5+模板。
Live Copy 不允许克隆页面是源页面的子页面。但是我被要求制作这样的网络结构:
Home |_ Page 1 |_ Page 1.1 |_ Page 2 |_ Page 3
Live Copy可能不适合这种情况,我们改为使用HTL ${inheritedPageProperties}
,这解决了模板和结构问题,但又产生了两个新问题:
子页面的 属性 配置对话框中的继承属性将为空白(因为它们未通过
${inheritedPageProperties}
设置和调用)如果用户更改 "Page 1" 页面中的属性,"Page 1.1"(和页面 1.1.1 等...)将使用这些值(因为
${inheritedPageProperties}
搜索上层节点以获取值)。
我们客户想要的是:
- 所有页面只能从主页或自己的页面使用导航设置(默认使用主页)。
- 如果使用主页属性,这些值必须显示在其配置对话框中。
- 尽量避免使用 CRXDE Lite 中的配置模板
- 网站必须有父子结构
我怎样才能达到这些要求?
您可以通过简单的 Sling Model and Sling's CompositeValueMap
CompositeValueMap 文档状态:
An implementation of the ValueMap based on two ValueMaps: - One containing the properties - Another one containing the defaults to use in case the properties map does not contain the values. In case you would like to avoid duplicating properties on multiple resources, you can use a CompositeValueMap to get a concatenated map of properties.
我们可以通过提供后代的值映射(当前页面的)然后找到正确的祖先并将其属性值映射作为默认值来使用它。
for the purposes of this question, I always assume that 2rd descendant from root is always the ancestor (you can find your ancestor according to your requirnments)
package com.sample.helpers;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.CompositeValueMap;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.apache.sling.models.annotations.injectorspecific.Self;
import javax.annotation.PostConstruct;
@Model(adaptables = Resource.class)
public class CustomInheritedPageProperties
{
ValueMap inheritedProperties;
@Self
Resource currentResource;
@OSGiService
PageManager pageManager;
@PostConstruct
protected void init() {
// get the current page, or the "descendant"
Page descendant = pageManager.getContainingPage(currentResource);
/* You have to add your custom logic to get the ancestor page.
* for this question's purposes, I'm always assuming it's the 3rd decendant of root
* more here: https://helpx.adobe.com/experience-manager/6-2/sites/developing/using/reference-materials/javadoc/com/day/cq/wcm/api/Page.html#getParent(int)
*/
Page ancestor = descendant.getParent(2);
// create a CompositeValueMap where the properties are descendant's and the defaults are ancestor's
inheritedProperties = new CompositeValueMap(descendant.getProperties(), ancestor.getProperties());
}
public ValueMap getInheritedProperties()
{
return inheritedProperties;
}
}
现在您可以按如下方式使用它
<sly data-sly-use.propHelper="com.sample.helpers.CustomInheritedPageProperties">>/sly>
<!--/* someProp here refers to the property you wish to get (inherited, of course)*/-->
<h1>propHelper.inheritedProperties.someProp</h1>