自定义AEM CIF核心组件

CIF Venia Project是使用CIF核心组件的参考代码库。 在本教程中,您将进一步扩展Product Teaser组件,以显示来自Magento的自定义属性。 您还将进一步了解AEM与Magento之间的GraphQL集成以及CIF核心组件提供的扩展挂钩。

小贴士

启动您自己的商务实施时,请使用AEM项目原型

您将要构建的内容

Venia品牌最近开始使用可持续材料生产某些产品,该企业希望在产品Teaser中显示​Eco Friendly​徽章。 将在Magento中创建新的自定义属性,以指示产品是否使用​Eco friendly​材料。 然后,此自定义属性将作为GraphQL查询的一部分添加,并显示在指定产品的Product Teaser中。

生态友好徽章最终实施

前提条件

需要本地开发环境才能完成本教程。 这包括已配置并连接到AEM实例的Magento实例。 查看使用AEM作为Cloud ServiceSDK设置本地开发的要求和步骤。 要完整地学习本教程,您需要拥有将属性添加到Magento中产品的权限。

您还需要GraphQL IDE(如GraphiQL)或浏览器扩展来运行代码示例和教程。 如果安装浏览器扩展,请确保它能够设置请求标头。 在Google Chrome上,Altair GraphQL客户端是可以执行该作业的扩展之一。

克隆Venia项目

我们将克隆Venia Project,然后覆盖默认样式。

注意

请随时使用现有项目 (基于包含CIF的AEM项目原型)并跳过此部分。

  1. 运行以下git命令以克隆项目:

    $ git clone git@github.com:adobe/aem-cif-guides-venia.git
    
  2. 构建项目并将其部署到AEM的本地实例:

    $ cd aem-cif-guides-venia/
    $ mvn clean install -PautoInstallPackage,cloud
    
  3. 添加必要的OSGi配置,以将您的AEM实例连接到Magento实例,或将配置添加到新创建的项目。

  4. 此时,您应该拥有连接到Magento实例的店面的工作版本。 导航到US > Home页面:http://localhost:4502/editor.html/content/venia/us/en.html

    您应会看到,当前的店面使用的是Venia主题。 展开店面的主菜单时,您应会看到各种类别,表示连接Magento正在工作。

    使用Venia主题配置的店面

创作Product Teaser

将在本教程中扩展产品Teaser组件。 第一步,将产品Teaser的新实例添加到主页以了解基线功能。

  1. 导航到网站的​主页:http://localhost:4502/editor.html/content/acme/us/en.html

  2. 将新的​Product Teaser​组件插入页面上的主布局容器。

    插入产品Teaser

  3. 展开侧面板(如果尚未切换),然后将资产查找器下拉列表切换到​Products。 这应会显示连接的Magento实例中可用产品的列表。 选择一个产品,然后将其拖放到页面上的​Product Teaser​组件上。

    拖放产品Teaser

    注意

    请注意,您还可以使用对话框配置组件(单击​_扳手_​图标)来配置显示的产品。

  4. 此时您应会看到产品Teaser正在显示。 产品名称和产品价格是显示的默认属性。

    产品Teaser — 默认样式

在Magento中添加自定义属性

AEM中显示的产品和产品数据存储在Magento中。 接下来,在使用MagentoUI设置的产品属性集中,为​Eco Friendly​添加新属性。

小贴士

您的产品属性集中是否已经具有自定义​Yes/No​属性? 请随时使用该插件并跳过此部分。

  1. 登录Magento实例。

  2. 导航到​Catalog > Products

  3. 更新搜索筛选器,以查找在上一练习中添加到Teaser组件时使用的​可配置产品。 在编辑模式下打开产品。

    搜索有效产品

  4. 在产品视图中,单击​添加属性 > 创建新属性

  5. 使用以下值填写​新建属性​表单(保留其他值的默认设置)

    字段集 字段标签
    属性属性 属性标签 生态友好
    属性属性 目录输入类型 是/否
    高级属性 属性代码 eco_friendly

    新属性表单

    完成后,单击​保存属性

  6. 滚动到产品底部并展开​Attributes​标题。 您应会看到新的​Eco Friendly​字段。 将切换开关切换到​Yes

    切换为是

    ​保存对产品所做的更改。

  7. 导航至​System > Tools > Cache Management。 由于对数据架构进行了更新,因此我们需要使Magento中的某些缓存类型失效。

  8. 选中​Configuration​旁边的复选框,并提交​Refresh​的缓存类型

    刷新配置缓存类型

使用GraphQL IDE验证属性

在跳入AEM代码之前,使用GraphQL IDE浏览MagentoGraphQL非常有用。 与AEM的Magento集成主要通过一系列GraphQL查询来完成。 了解和修改GraphQL查询是扩展CIF核心组件的关键方法之一。

接下来,使用GraphQL IDE验证eco_friendly属性是否已添加到产品属性集。 本教程中的屏幕截图使用Altair GraphQL客户端

  1. 打开GraphQL IDE,然后在IDE或扩展的URL栏中输入URL http://<magento-server>/graphql

  2. 添加以下产品查询,其中YOUR_SKU是上一个练习中使用的产品的​SKU:

      {
        products(
        filter: { sku: { eq: "YOUR_SKU" } }
        ) {
            items {
            name
            sku
            eco_friendly
            }
        }
    }
    
  3. 执行查询,您应获得如下响应:

    {
      "data": {
        "products": {
          "items": [
            {
              "name": "Valeria Two-Layer Tank",
              "sku": "VT11",
              "eco_friendly": 1
            }
          ]
        }
      }
    }
    

    示例GraphQL响应

    请注意,Yes​的值是​1​的整数。 当我们使用Java编写GraphQL查询时,这将非常有用。

更新Product Teaser的Sling模型

接下来,我们将通过实施Sling模型来扩展产品Teaser的业务逻辑。 Sling模型是注释驱动的“POJO”(纯旧Java对象),用于实施组件所需的任何业务逻辑。Sling模型会与HTL脚本一起用作组件的一部分。 我们将遵循Sling模型🔗的委派模式,以便我们只需扩展现有Product Teaser模型的部分内容即可。

Sling模型将作为Java实施,并可在生成项目的​core​模块中找到。

使用您选择的IDE导入Venia项目。 使用的屏幕截图来自Visual Studio代码IDE

  1. 在IDE的​core​模块下,导航到:core/src/main/java/com/venia/core/models/commerce/MyProductTeaser.java

    核心位置IDE

    MyProductTeaser.java 是一个Java界面,用于扩展CIF ProductTeaser 🔗 界面。

    已添加名为isShowBadge()的新方法,如果产品被视为“New”,则会显示标记。

  2. 在接口中添加新方法isEcoFriendly() :

    @ProviderType
    public interface MyProductTeaser extends ProductTeaser {
        // Extend the existing interface with the additional properties which you
        // want to expose to the HTL template.
        public Boolean isShowBadge();
    
        public Boolean isEcoFriendly();
    }
    

    我们将引入这种新方法来封装逻辑,以指示产品是否将eco_friendly属性设置为​Yes​或​No

  3. 接下来,在core/src/main/java/com/venia/core/models/commerce/MyProductTeaserImpl.java检查MyProductTeaserImpl.java

    Sling模型的委派模式允许MyProductTeaserImpl通过sling:resourceSuperType属性引用ProductTeaser模型:

    @Self
    @Via(type = ResourceSuperType.class)
    private ProductTeaser productTeaser;
    

    对于我们不希望覆盖或更改的所有方法,我们只需返回ProductTeaser返回的值即可。 例如:

    @Override
    public String getImage() {
        return productTeaser.getImage();
    }
    

    这可以最大限度地减少实施需要写入的Java代码量。

  4. AEM CIF核心组件提供的额外扩展点之一是AbstractProductRetriever,它提供了对特定产品属性的访问权限。 Inspect initModel()方法:

    import javax.annotation.PostConstruct;
    ...
    @Model(adaptables = SlingHttpServletRequest.class, adapters = MyProductTeaser.class, resourceType = MyProductTeaserImpl.RESOURCE_TYPE)
    public class MyProductTeaserImpl implements MyProductTeaser {
        ...
        private AbstractProductRetriever productRetriever;
    
        /* add this method to intialize the proudctRetriever */
        @PostConstruct
        public void initModel() {
            productRetriever = productTeaser.getProductRetriever();
    
            if (productRetriever != null) {
                productRetriever.extendProductQueryWith(p -> p.createdAt());
            }
    
        }
    ...
    

    @PostConstruct注释可确保在初始化Sling模型后立即调用此方法。

    请注意,产品GraphQL查询已使用extendProductQueryWith方法进行扩展,以检索附加的created_at属性。 此属性稍后用作isShowBadge()方法的一部分。

  5. 更新GraphQL查询,以在部分查询中包含eco_friendly属性:

    //MyProductTeaserImpl.java
    
    private static final String ECO_FRIENDLY_ATTRIBUTE = "eco_friendly";
    
    @PostConstruct
    public void initModel() {
        productRetriever = productTeaser.getProductRetriever();
    
        if (productRetriever != null) {
            productRetriever.extendProductQueryWith(p ->
                 productRetriever.extendProductQueryWith(p -> p
                    .createdAt()
                    .addCustomSimpleField(ECO_FRIENDLY_ATTRIBUTE)
                );
            );
        }
    }
    

    extendProductQueryWith方法添加是确保其他产品属性可用于模型其余部分的一种有效方法。 它还可以最大限度地减少所执行查询的数量。

    在上述代码中,addCustomSimpleField用于检索eco_friendly属性。 这说明了如何查询属于Magento架构的任何自定义属性。

    注意

    createdAt()方法实际上已作为产品界面的一部分实施。 大多数常见的架构属性都已实施,因此,请仅使用addCustomSimpleField获取真正的自定义属性。

  6. 添加日志记录器以帮助调试Java代码:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    ...
    @Model(adaptables = SlingHttpServletRequest.class, adapters = MyProductTeaser.class, resourceType = MyProductTeaserImpl.RESOURCE_TYPE)
    public class MyProductTeaserImpl implements MyProductTeaser {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(MyProductTeaserImpl.class);
    
  7. 接下来,实施isEcoFriendly()方法:

    @Override
    public Boolean isEcoFriendly() {
    
        Integer ecoFriendlyValue;
        try {
            ecoFriendlyValue = productRetriever.fetchProduct().getAsInteger(ECO_FRIENDLY_ATTRIBUTE);
            if(ecoFriendlyValue != null && ecoFriendlyValue.equals(Integer.valueOf(1))) {
                LOGGER.info("*** Product is Eco Friendly**");
                return true;
            }
        } catch (SchemaViolationError e) {
            LOGGER.error("Error retrieving eco friendly attribute");
        }
        LOGGER.info("*** Product is not Eco Friendly**");
        return false;
    }
    

    在上述方法中,使用productRetriever获取产品,使用getAsInteger()方法获取eco_friendly属性的值。 根据我们之前运行的GraphQL查询,我们知道当eco_friendly属性设置为“Yes”时的预期值实际上是​1​的整数。

    现在,Sling模型已更新,需要更新组件标记,以便根据Sling模型实际显示​Eco Friendly​的指示器。

自定义Product Teaser的标记

AEM组件的常见扩展是修改由组件生成的标记。 这是通过覆盖组件用于呈现其标记的HTL脚本来完成的。 HTML模板语言(HTL)是一种轻量级的模板语言,AEM组件使用它根据创作内容动态渲染标记,从而允许重复使用组件。 例如,可以反复重复使用产品Teaser来显示不同的产品。

在本例中,我们要在Teaser顶部渲染一个横幅,以指示产品基于自定义属性为“生态友好”。 自定义组件标记的设计模式实际上是所有AEM组件的标准模式,而不仅仅是AEM CIF核心组件的标准模式。

注意

如果您使用CIF产品和类别选取器(如此Product Teaser或CIF页面组件)自定义组件,请确保为组件对话框包含所需的cif.shell.picker clientlib。 有关详细信息,请参阅CIF产品和类别选取器的使用

  1. 在IDE中,导航并展开ui.apps模块,然后展开文件夹层次结构以:ui.apps/src/main/content/jcr_root/apps/venia/components/commerce/productteaser并检查.content.xml文件。

    产品Teaser ui.apps

    <?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"
        jcr:description="Product Teaser Component"
        jcr:primaryType="cq:Component"
        jcr:title="Product Teaser"
        sling:resourceSuperType="core/cif/components/commerce/productteaser/v1/productteaser"
        componentGroup="Venia - Commerce"/>
    

    上面是我们项目中Product Teaser组件的组件定义。 请注意属性sling:resourceSuperType="core/cif/components/commerce/productteaser/v1/productteaser"。 以下是创建代理组件的示例。 我们可以使用sling:resourceSuperType继承所有功能,而不是从AEM CIF核心组件中复制和粘贴所有Product Teaser HTL脚本。

  2. 打开文件productteaser.html。 这是CIF Product Teaserproductteaser.html文件的副本

    <!--/* productteaser.html */-->
    <sly
      data-sly-use.product="com.venia.core.models.commerce.MyProductTeaser"
      data-sly-use.templates="core/wcm/components/commons/v1/templates.html"
      data-sly-use.actionsTpl="actions.html"
      data-sly-test.isConfigured="${properties.selection}"
      data-sly-test.hasProduct="${product.url}"
    ></sly>
    

    请注意,已使用MyProductTeaser的Sling模型,并将其分配给product变量。

  3. 修改productteaser.html以调用上一个练习中实现的isEcoFriendly方法:

    ...
    <div
      data-sly-test="${isConfigured && hasProduct}"
      class="item__root"
      data-cmp-is="productteaser"
      data-virtual="${product.virtualProduct}"
    >
      <div data-sly-test="${product.showBadge}" class="item__badge">
        <span>${properties.text || 'New'}</span>
      </div>
      <!--/* Insert call to Eco Friendly here */-->
      <div data-sly-test="${product.ecoFriendly}" class="item__eco">
        <span>Eco Friendly</span>
      </div>
      ...
    </div>
    

    在HTL中调用Sling Model方法时,将删除该方法的getis部分,并将第一个字母小写。 因此,isShowBadge()变为.showBadge,isEcoFriendly变为.ecoFriendly。 根据从.isEcoFriendly()返回的布尔值确定是否显示<span>Eco Friendly</span>

    有关data-sly-test和其他HTL块语句的更多信息,请参阅此处

  4. 通过命令行终端保存更改并使用您的Maven技能部署对AEM的更新:

    $ cd aem-cif-guides-venia/
    $ mvn clean install -PautoInstallPackage,cloud
    
  5. 打开新的浏览器窗口,然后导航到AEM和​OSGi控制台 > 状态 > Sling模型:http://localhost:4502/system/console/status-slingmodels

  6. 搜索MyProductTeaserImpl,您应会看到如下行:

    com.venia.core.models.commerce.MyProductTeaserImpl - venia/components/commerce/productteaser
    

    这表示Sling模型已正确部署并映射到正确的组件。

  7. http://localhost:4502/editor.html/content/venia/us/en.html的​Venia主页​中刷新到已添加Product Teaser的Venia主页。

    显示生态友好消息

    如果产品的eco_friendly属性设置为​Yes,则页面上应显示“Eco Friendly”文本。 尝试切换到不同的产品以查看行为更改。

  8. 接下来,打开AEM error.log以查看我们添加的log语句。 error.log位于<AEM SDK Install Location>/crx-quickstart/logs/error.log

    搜索AEM日志以查看在Sling模型中添加的log语句:

    2020-08-28 12:57:03.114 INFO [com.venia.core.models.commerce.MyProductTeaserImpl] *** Product is Eco Friendly**
    ...
    2020-08-28 13:01:00.271 INFO [com.venia.core.models.commerce.MyProductTeaserImpl] *** Product is not Eco Friendly**
    ...
    
    注意

    如果在Teaser中使用的产品在其属性集中没有eco_friendly属性,则还可能会看到一些堆栈跟踪。

添加Eco友好徽章的样式

此时,显示​Eco Friendly​徽章的时间逻辑正在工作,但纯文本可能使用某些样式。 接下来,向ui.frontend模块添加图标和样式以完成实施。

  1. 下载eco_friendly.svg文件。 此标记将用作​Eco Friendly​标记。

  2. 返回到IDE并导航到ui.frontend文件夹。

  3. eco_friendly.svg文件添加到ui.frontend/src/main/resources/images文件夹中:

    添加了Eco友好SVG

  4. ui.frontend/src/main/styles/commerce/_productteaser.scss处打开文件productteaser.scss

  5. .productteaser类中添加以下Sass规则:

    .productteaser {
        ...
        .item__eco {
            width: 60px;
            height: 60px;
            left: 0px;
            overflow: hidden;
            position: absolute;
            padding: 5px;
    
        span {
            display: block;
            position: absolute;
            width: 45px;
            height: 45px;
            text-indent: -9999px;
            background: no-repeat center center url('../resources/images/eco_friendly.svg');
            }
        }
    ...
    }
    
    注意

    有关前端工作流的更多详细信息,请参阅样式CIF核心组件

  6. 通过命令行终端保存更改并使用您的Maven技能部署对AEM的更新:

    $ cd aem-cif-guides-venia/
    $ mvn clean install -PautoInstallPackage,cloud
    
  7. http://localhost:4502/editor.html/content/venia/us/en.html的​Venia主页​中刷新到已添加Product Teaser的Venia主页。

    生态友好徽章最终实施

恭喜

您刚刚自定义了第一个AEM CIF组件! 在此处🔗下载已完成的解决方案文件。

附加练习

查看​New​标记的功能,该标记已在Product Teaser中实施。 尝试为作者添加一个额外的复选框,以控制何时应显示​Eco Friendly​标记。 您需要更新位于ui.apps/src/main/content/jcr_root/apps/venia/components/commerce/productteaser/_cq_dialog/.content.xml的组件对话框。

新徽章实施挑战

其他资源

在此页面上