代码之家  ›  专栏  ›  技术社区  ›  Hai Hoang

如何在AEM 6.2中继承页面属性?

aem
  •  3
  • Hai Hoang  · 技术社区  · 7 年前

    在我们的AEM 6.2项目中,我遇到了一个场景,需要在一个页面中配置导航(我们称之为主页),其他所有页面都可以使用主页导航配置或使用自己的导航配置值。

    我决定使用live copy,因为克隆页面可以随时取消链接属性并使用它们自己的值。但这种方法有两个问题:

    1. 用户必须通过编辑其jcr:content/sling:resourceType和jcr:content/cq:template来设置克隆页面的模板,因为导航用于所有页面,我们的网站使用大约5个以上的模板。
    2. Live copy不允许克隆页是源页的子级。但我被要求制作这样的web结构:

      Home
         |_ Page 1
                  |_ Page 1.1
         |_ Page 2
         |_ Page 3
      

    Live copy可能不适合这种情况,我们改为使用HTL ${inheritedPageProperties} ,这解决了模板和结构问题,但也带来了两个新问题:

    1. 子页的“属性配置”对话框中的继承属性将为空(因为它们未通过设置和调用 ${inheritedPageProperties} )

    2. 如果用户更改“第1页”页面、“第1.1页”(和第1.1.1页等)中的属性将使用这些值(因为 ${inheritedPageProperties} 搜索上部节点以获取值)。

    我们的客户想要的是:

    • 所有页面只能从主页或其自己的页面使用导航设置(默认情况下使用主页)。
    • 如果使用主页属性,这些值必须显示在其配置对话框中。
    • 尽量避免在CRXDE Lite中使用配置模板
    • 网站必须具有父子结构

    如何实现这些要求?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Ahmed Musallam    7 年前

    您可以通过一个简单的 Sling Model 和吊索 CompositeValueMap

    CompositeValueMap文档状态:

    基于两个ValueMap的ValueMap实现:-一个包含属性-另一个包含属性映射不包含值时使用的默认值。如果希望避免在多个资源上重复属性,可以使用CompositeValueMap来获取属性的串联映射。

    我们可以通过提供子代的值映射(当前页的值映射),然后找到正确的祖先,并提供其属性值映射作为默认值来使用它。

    就这个问题而言,我总是假设根的2rd后代永远是祖先(你可以根据你的要求找到你的祖先)

    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>