扩展AEM Screens组件

以下教程将介绍扩展开箱即用式AEM Screens组件的步骤和最佳实践。 图像组件经过扩展以添加可创作的文本叠加。

概述

本教程面向初次接触AEM Screens的开发人员。 在本教程中,Screens图像组件经过扩展以创建海报组件。 标题、描述和徽标会叠加在图像顶部,以在序列渠道中创建引人入胜的体验。

注意

在开始本教程之前,建议您先完成本教程:开发AEM Screens的自定义组件

自定义海报组件

自定义海报组件是通过扩展图像组件创建的。

前提条件

要完成本教程,需要执行以下操作:

  1. AEM 6.4AEM 6. 3+最新屏幕功能包
  2. AEM Screens 播放器
  3. 本地开发环境

教程步骤和屏幕截图是使用CRXDE-Lite执行的。 Eclipseor IntelliJIDE还可用于完成教程。有关使用IDE与AEM进行开发的更多信息,请访问

项目设置

Screens项目的源代码通常作为多模块Maven项目进行管理。 为加快教程的进度,已使用AEM项目原型13预生成一个项目。 有关使用Maven AEM项目原型创建项目的详细信息,请参阅此处

  1. 使用​CRX包管理 http://localhost:4502/crx/packmgr/index.jsp)r:下载并安装以下包

    获取文件

    获取文件
    (可选) 如果使用Eclipse或其他IDE,请下载以下源包。使用Maven命令将项目部署到本地AEM实例:

    mvn -PautoInstallPackage clean install

    SRC开始屏幕We.Retail运行项目

    获取文件

  2. 在​CRX包管理器 http://localhost:4502/crx/packmgr/index.jsp中,安装了以下两个包:

    1. screens-weretail-run.ui.content-0.0.1-SNAPSHOT.zip
    2. screens-weretail-run.ui.apps-0.0.1-SNAPSHOT.zip

    Screens We.Retail运行通过CRX包管理器安装的Ui.Apps和Ui.Content包

    Screens We.Retail运行通过CRX包管理器安装的Ui.Apps和Ui.Content包

创建海报组件

海报组件扩展了现成的屏幕图像组件。 Sling的机制sling:resourceSuperType用于继承图像组件的核心功能,而无需复制和粘贴。 有关Sling请求处理基础知识的更多信息,请访问此处。

海报组件以全屏方式以预览/制作模式呈现。 在编辑模式下,为了便于创作序列渠道,必须以不同方式呈现组件。

  1. 在​下方的/apps/weretail-run/components/contentCRXDE-Lite http://localhost:4502/crx/de/index.jsp(或选择的IDE)中,创建一个名为poster的新cq:Component

    poster组件添加以下属性:

    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0" xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0"
        jcr:primaryType="cq:Component"
        jcr:title="Poster"
        sling:resourceSuperType="screens/core/components/content/image"
        componentGroup="We.Retail Run - Content"/>
    

    /apps/weretail-run/components/content/poster的属性

    /apps/weretail-run/components/content/poster的属性

    通过将sling:resourceSuperType属性设置为等于screens/core/components/content/image,海报组件可以有效地继承图像组件的所有功能。 可以在screens/core/components/content/image组件下添加位于poster下的对等节点和文件,以覆盖和扩展功能。

  2. cq:editConfig节点复制到/libs/screens/core/components/content/image.组件下方的cq:editConfig中。/apps/weretail-run/components/content/poster

    cq:editConfig/cq:dropTargets/image/parameters节点上,将sling:resourceType属性更新为等于weretail-run/components/content/poster

    edit-config

    cq:editConfig的XML表示形式如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0" xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0" xmlns:nt="https://www.jcp.org/jcr/nt/1.0"
        jcr:primaryType="cq:EditConfig">
        <cq:dropTargets jcr:primaryType="nt:unstructured">
            <image
                jcr:primaryType="cq:DropTargetConfig"
                accept="[image/.*]"
                groups="[media]"
                propertyName="./fileReference">
                <parameters
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="weretail-run/components/content/poster"
                    imageCrop=""
                    imageMap=""
                    imageRotate=""/>
            </image>
        </cq:dropTargets>
    </jcr:root>
    
  3. 复制要用于poster组件的WCM Foundation image对话框。

    最容易从现有对话框中开始,然后进行修改。

    1. 从以下位置复制对话框:/libs/wcm/foundation/components/image/cq:dialog
    2. 将对话框粘贴到/apps/weretail-run/components/content/poster下方

    将对话框从/libs/wcm/foundation/components/image/cq:dialog复制到/apps/weretail-run/components/content/poster

    将对话框从/libs/wcm/foundation/components/image/cq:dialog复制到/apps/weretail-run/components/content/poster

    Screens image组件被超类型化到WCM Foundation image组件。 因此,poster组件从两者继承了功能。 海报组件的对话框由“屏幕”和“基础”对话框的组合组成。 Sling资源合并​的功能用于隐藏从超类型组件继承的无关对话框字段和选项卡。

  4. 使用XML中显示的以下更改更新/apps/weretail-run/components/content/poster下方的cq:dialog:

    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0" xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0" xmlns:nt="https://www.jcp.org/jcr/nt/1.0"
        jcr:primaryType="nt:unstructured"
        jcr:title="Poster"
        sling:resourceType="cq/gui/components/authoring/dialog">
        <content
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/foundation/container">
            <layout
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/foundation/layouts/tabs"
                type="nav"/>
            <items jcr:primaryType="nt:unstructured">
                <image
                    jcr:primaryType="nt:unstructured"
                    jcr:title="Elements"
                    sling:resourceType="granite/ui/components/foundation/section">
                    <layout
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
                        margin="{Boolean}false"/>
                    <items jcr:primaryType="nt:unstructured">
                        <column
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/foundation/container">
                            <items
                                jcr:primaryType="nt:unstructured"
                                sling:hideChildren="[linkURL,size]">
                                <file
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="cq/gui/components/authoring/dialog/fileupload"
                                    autoStart="{Boolean}false"
                                    class="cq-droptarget"
                                    fieldLabel="Image asset"
                                    fileNameParameter="./fileName"
                                    fileReferenceParameter="./fileReference"
                                    mimeTypes="[image]"
                                    multiple="{Boolean}false"
                                    name="./file"
                                    title="Upload Image Asset"
                                    uploadUrl="${suffix.path}"
                                    useHTML5="{Boolean}true"/>
                                <title
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/foundation/form/textfield"
                                    fieldLabel="Title"
                                    name="./jcr:title"/>
                                <description
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/foundation/form/textarea"
                                    fieldLabel="Description"
                                    name="./jcr:description"/>
                                <position
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/coral/foundation/form/select"
                                    fieldLabel="Text Position"
                                    name="./textPosition">
                                    <items jcr:primaryType="nt:unstructured">
                                        <left
                                            jcr:primaryType="nt:unstructured"
                                            text="Left"
                                            value="left"/>
                                        <center
                                            jcr:primaryType="nt:unstructured"
                                            text="Center"
                                            value="center"/>
                                        <right
                                            jcr:primaryType="nt:unstructured"
                                            text="Right"
                                            value="right"/>
                                    </items>
                                </position>
                                <color
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/coral/foundation/form/select"
                                    fieldLabel="Text Color"
                                    name="./textColor">
                                    <items jcr:primaryType="nt:unstructured">
                                        <light
                                            jcr:primaryType="nt:unstructured"
                                            text="Light"
                                            value="light"/>
                                        <dark
                                            jcr:primaryType="nt:unstructured"
                                            text="Dark"
                                            value="dark"/>
                                    </items>
                                </color>
                            </items>
                        </column>
                    </items>
                </image>
                <accessibility
                    jcr:primaryType="nt:unstructured"
                    sling:hideResource="{Boolean}true"/>
            </items>
        </content>
    </jcr:root>
    

    items节点上使用属性sling:hideChildren= "[linkURL,size]",以确保对话框中隐藏​linkURL​和​size​字段。 仅从海报对话框中删除这些节点是不够的。 辅助功能选项卡上的属性sling:hideResource="{Boolean}true"用于隐藏整个选项卡。

    在对话框中添加了两个选择字段,以使作者能够控制标题和说明的文本位置和颜色。

    海报 — 最终对话框结构

    海报 — 最终对话框结构

    此时,可以将poster组件的实例添加到We.Retail Run项目的​Idle 渠道​页面:http://localhost:4502/editor.html/content/screens/we-retail-run/channels/idle-channel.edit.html

    海报对话框字段

    海报对话框字段

  5. /apps/weretail-run/components/content/poster下创建名为production.html.的文件

    使用以下内容填充文件:

    <!--/*
    
        /apps/weretail-run/components/content/poster/production.html
    
    */-->
    <div data-sly-use.image="image.js"
         data-duration="${properties.duration}"
         class="cmp-poster"
         style="background-image: url(${request.contextPath @ context='uri'}${image.src @ context='uri'});">
        <div class="cmp-poster__text
                    cmp-poster__text--${properties.textPosition @ context='attribute'}
                    cmp-poster__text--${properties.textColor @ context='attribute'}">
            <h1 class="cmp-poster__title">${properties.jcr:title}</h1>
             <h2 class="cmp-poster__description">${properties.jcr:description}</h2>
        </div>
     <img class="cmp-poster__logo" src="/content/dam/we-retail-run/logos/we-retail-run_dark.png?lang=zh-Hans" alt="we-retail-logo" />
    </div>
    

    以上是海报组件的制作标记。 HTL脚本将覆盖screens/core/components/content/image/production.htmlimage.js是创建类似POJO的Image对象的服务器端脚本。 然后,可以调用Image对象以将src渲染为内联样式background-image。

    The h1 添加h2标记后,会根据组件属性显示标题和说明: ${properties.jcr:title}${properties.jcr:description}

    h1h2标记周围是一个div包装器,包含三个CSS类,变量为" cmp-poster__text"。 textPositiontextColor属性的值用于根据作者的对话框选择更改呈现的CSS类。 在下一节中,将编写客户端库中的CSS,以在显示中启用这些更改。

    徽标也作为叠加包含在组件中。 在此示例中,We.Retail徽标的路径硬编码在DAM中。 根据用例,创建新对话框字段可使徽标路径成为动态填充的值可能更有意义。

    另请注意,组件中使用了BEM(块元素修饰符)记号。 BEM是一种CSS编码约定,它使创建可重用组件更加容易。 BEM是AEM核心组件使用的记号。 有关更多信息,请访问:https://getbem.com/

  6. /apps/weretail-run/components/content/poster下创建名为edit.html.的文件

    使用以下内容填充文件:

    <!--/*
    
        /apps/weretail-run/components/content/poster/edit.html
    
    */-->
    
    <div class="aem-Screens-editWrapper ${image.cssClass} cmp-poster" data-sly-use.image="image.js" data-emptytext="${'Poster' @ i18n, locale=request.locale}">
        <img class="cmp-poster__image" src="${request.contextPath}${image.src @ context='uri'}" width="100%" />
        <div class="cmp-poster__text
               cmp-poster__text--${properties.textPosition @ context='attribute'}
           cmp-poster__text--${properties.textColor @ context='attribute'}">
          <p class="cmp-poster__title">${properties.jcr:title}</p>
          <p class="cmp-poster__description">${properties.jcr:description}</p>
        </div>
    </div>
    

    上面是海报组件的​edit​标记。 HTL脚本将覆盖/libs/screens/core/components/content/image/edit.html。 标记与production.html标记类似,并将在图像顶部显示标题和说明。

    将添加aem-Screens-editWrapper,以便组件不会在编辑器中呈现全屏。 data-emptytext属性确保在未填充图像或内容时显示占位符。

创建客户端库

客户端库提供了组织和管理AEM实施所需的CSS和JavaScript文件的机制。 有关使用客户端库的详细信息,请访问此处。

AEM Screens组件在编辑模式与预览/生产模式下的呈现方式不同。 将创建两组客户端库,一组用于编辑模式,另一组用于预览/生产。

  1. 为海报组件的客户端库创建文件夹。

    /apps/weretail-run/components/content/poster,下面创建一个名为clientlibs的新文件夹。

    2018-05-03_at_1008pm

  2. clientlibs文件夹下,创建一个名为shared的类型为cq:ClientLibraryFolder.的新节点

    2018-05-03_at_1011pm

  3. 将以下属性添加到共享客户端库:

    • allowProxy | 布尔型 | true
    • categories | String[] | cq.screens.components

    /apps/weretail-run/components/content/poster/clientlibs/shared的属性

    /apps/weretail-run/components/content/poster/clientlibs/shared的属性

    categories属性是标识客户端库的字符串。 cq.screens.components类别在“编辑”和“预览/生产”模式下均使用。 因此,在shared clientlib中定义的所有CSS/JS都会以所有模式加载。

    绝不直接在生产环境中向/apps公开任何路径是最佳做法。 allowProxy属性确保客户端库CSS和JS通过前缀/etc.clientlibs引用。 有关allowProxy属性的详细信息,请访问此处。

  4. 在共享文件夹下创建名为css.txt的文件。

    使用以下内容填充文件:

    #base=css
    
    styles.less
    
  5. shared文件夹下创建一个名为css的文件夹。 在css文件夹下添加一个名为style.less的文件。 客户端库的结构现在应当如下:

    2018-05-03_at_1057pm

    本教程使用LESS,而不是直接编写CSS。 LESS 是一款流行的CSS预编译器,它支持CSS变量、混合和函数。AEM客户端库本身支持LESS编译。 Sass或其他预编译器可以使用,但需要在AEM外部编译。

  6. 使用以下内容填充/apps/weretail-run/components/content/poster/clientlibs/shared/css/styles.less:

    /*
     /apps/weretail-run/components/content/poster/clientlibs/shared/css/styles.less
     Poster Component - Shared Style
    */
    
    @import url('https://fonts.googleapis.com/css?family=Fjalla+One|Open+Sans:400i');
    
    @text-light-color: #fff;
    @text-dark-color: #000;
    @title-font-family: 'Fjalla One', sans-serif;
    @description-font-family: 'Open Sans', sans-serif;
    
    .cmp-poster {
    
          &__text {
          position: absolute;
          color: @text-light-color;
          top: 0;
          text-align:center;
          width: 100%;
    
          &--left {
           text-align: left;
                 margin-left: 1em;
          }
    
          &--right {
           text-align: right;
                 margin-right: 1em;
          }
    
          &--dark {
           color: @text-dark-color;
          }
        }
    
        &__title {
          font-weight: bold;
             font-family: @title-font-family;
             font-size: 1.2em;
        }
    
        &__description {
      font-style: italic;
            font-family: @description-font-family;
     }
    
    }
    
    注意

    Google Web字体用于字体系列。 Web字体需要Internet连接,并且并非所有屏幕实现都会可靠连接。 计划脱机模式是Screens部署的重要考虑事项。

  7. 复制shared客户端库文件夹。 将其粘贴为同级文件,并将其重命名为production

    2018-05-03_at_1114pm

  8. 将生产clientlibrary的categories属性更新为cq.screens.components.production.

    cq.screens.components.production类别确保样式仅在预览/生产模式下加载。

    /apps/weretail-run/components/content/poster/clientlibs/production的属性

    /apps/weretail-run/components/content/poster/clientlibs/production的属性

  9. 使用以下内容填充/apps/weretail-run/components/content/poster/clientlibs/production/css/styles.less:

    /*
     /apps/weretail-run/components/content/poster/clientlibs/production/css/styles.less
     Poster Component - Production Style
    */
    
    .cmp-poster {
    
        background-size: cover;
     height: 100%;
     width: 100%;
     position:absolute;
    
         &__text {
    
            top: 2em;
    
            &--left {
                width: 40%;
                top: 5em;
            }
    
            &--right {
                width: 40%;
                right: 1em;
            }
        }
    
        &__title {
      font-size: 5rem;
      font-weight: 900;
      margin: 0.1rem;
     }
    
     &__description {
      font-size: 2rem;
      margin: 0.1rem;
      font-weight: 400;
    
     }
    
        &__logo {
      position: absolute;
      max-width: 200px;
      top: 1em;
      left: 0;
     }
    
    }
    

    上述样式在屏幕上的绝对位置显示标题和说明。 标题将显示得比描述大很多。 使用组件的BEM记号可以非常轻松地在cmp-poster类中仔细地调整样式范围。

第三个clientlibrary类别:cq.screens.components.edit可用于向组件添加仅编辑特定样式。

Clientlib类别 使用
cq.screens.components 在编辑和制作模式之间共享的样式和脚本
cq.screens.components.edit 仅在编辑模式下使用的样式和脚本
cq.screens.components.production 仅在生产模式中使用的样式和脚本

将海报组件添加到序列渠道

海报组件旨在用于序列渠道。 本教程的启动包包含一个空闲渠道。 空闲渠道已预配置为允许组​We.Retail Run - Content​的组件。 海报组件的组设置为We.Retail Run - Content,可添加到渠道。

  1. 从We.Retail Run项目打开Idle渠道:http://localhost:4502/editor.html/content/screens/we-retail-run/channels/idle-channel.edit.html

  2. 将​Poster​组件的新实例从页面的侧栏拖放到页面。

    2018-05-07_at_3_23pm

  3. 编辑海报组件的对话框以添加图像、标题和说明。 使用“文本位置”和“文本颜色”选项可确保在图像上可读取标题/说明。

    2018-05-07_at_3_25pm

  4. 重复上述步骤以添加一些海报组件。 在组件之间添加过渡。

    2018-05-07_at_3_28pm

将所有内容组合在一起

以下视频显示完成的组件以及如何将其添加到序列渠道。 然后,该渠道将添加到“位置”显示屏,并最终分配到Screens播放器。

完成的代码

下面是教程中完成的代码。 screens-weretail-run.ui.apps-0.0.1-SNAPSHOT.zip​和​screens-weretail-run.ui.content-0.0.1-SNAPSHOT.zip​是编译的AEM包。 SRC-screens-weretail-run-0.0.1.zip 是未编译的源代码,可使用Maven进行部署。

获取文件

获取文件

SRC Final Screens We.Retail运行项目

获取文件

On this page

Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now