可编辑的容器组件

固定组件为创作SPA内容提供了一些灵活性,但这种方法很僵化,需要开发人员定义可编辑内容的确切构成。 为了支持作者创建例外体验,SPA编辑器支持在SPA中使用容器组件。 容器组件允许作者将允许的组件拖放到容器中并进行创作,就像在传统AEM Sites创作中一样!

可编辑的容器组件

在本章中,我们向“主页”视图添加了一个可编辑的容器,该容器允许作者直接在SPA中使用可编辑的React组件来创作和布局丰富的内容体验。

更新WKND应用程序

要将容器组件添加到“主页”视图,请执行以下操作:

  • 导入AEM React可编辑组件的ResponsiveGrid组件
  • 导入并注册自定义可编辑的React组件(文本和图像),以便在ResponsiveGrid组件中使用

使用ResponsiveGrid组件

要将可编辑区域添加到“主页”视图,请执行以下操作:

  1. 打开并编辑react-app/src/components/Home.js

  2. @adobe/aem-react-editable-components导入ResponsiveGrid组件并将其添加到Home组件。

  3. <ResponsiveGrid...>组件上设置以下属性

    • pagePath = '/content/wknd-app/us/en/home'
    • itemPath = 'root/responsivegrid'

    这会指示ResponsiveGrid组件从AEM资源检索其内容:

    • /content/wknd-app/us/en/home/jcr:content/root/responsivegrid

    itemPath映射到在Remote SPA Page AEM模板中定义的responsivegrid节点,并在从Remote SPA Page AEM模板创建的新AEM页面上自动创建。

    更新Home.js以添加<ResponsiveGrid...>组件。

    code language-javascript
    ...
    import { ResponsiveGrid } from '@adobe/aem-react-editable-components';
    ...
    
    function Home() {
        return (
            <div className="Home">
                <ResponsiveGrid
                    pagePath='/content/wknd-app/us/en/home'
                    itemPath='root/responsivegrid'/>
    
                <EditableTitle
                    pagePath='/content/wknd-app/us/en/home'
                    itemPath='title'/>
    
                <Adventures />
            </div>
        );
    }
    

Home.js文件应如下所示:

Home.js

创建可编辑的组件

充分利用SPA编辑器中提供的灵活创作体验容器。 我们已经创建了一个可编辑的标题组件,但让我们再执行一些操作,以允许作者在新添加的ResponsiveGrid组件中使用可编辑的文本和图像组件。

新的可编辑文本和图像React组件是使用在可编辑的固定组件中公开的可编辑组件定义模式创建的。

可编辑文本组件

  1. 在IDE中打开SPA项目

  2. src/components/editable/core/Text.js处创建React组件

  3. 将以下代码添加到Text.js

    code language-javascript
    import React from 'react'
    
    const TextPlain = (props) => <div className={props.baseCssClass}><p className="cmp-text__paragraph">{props.text}</p></div>;
    const TextRich = (props) => {
    const text = props.text;
    const id = (props.id) ? props.id : (props.cqPath ? props.cqPath.substr(props.cqPath.lastIndexOf('/') + 1) : "");
        return <div className={props.baseCssClass} id={id} data-rte-editelement dangerouslySetInnerHTML={{ __html: text }} />
    };
    
    export const Text = (props) => {
        if (!props.baseCssClass) {
            props.baseCssClass = 'cmp-text'
        }
    
        const { richText = false } = props
    
        return richText ? <TextRich {...props} /> : <TextPlain {...props} />
        }
    
        export function textIsEmpty(props) {
        return props.text == null || props.text.length === 0;
    }
    
  4. src/components/editable/EditableText.js处创建可编辑的React组件

  5. 将以下代码添加到EditableText.js

    code language-javascript
    import React from 'react'
    import { EditableComponent, MapTo } from '@adobe/aem-react-editable-components';
    import { Text, textIsEmpty } from "./core/Text";
    import { withConditionalPlaceHolder } from "./core/util/withConditionalPlaceholder";
    import { withStandardBaseCssClass } from "./core/util/withStandardBaseCssClass";
    
    const RESOURCE_TYPE = "wknd-app/components/text";
    
    const EditConfig = {
        emptyLabel: "Text",
        isEmpty: textIsEmpty,
        resourceType: RESOURCE_TYPE
    };
    
    export const WrappedText = (props) => {
        const Wrapped = withConditionalPlaceHolder(withStandardBaseCssClass(Text, "cmp-text"), textIsEmpty, "Text V2")
        return <Wrapped {...props} />
    };
    
    const EditableText = (props) => <EditableComponent config={EditConfig} {...props}><WrappedText /></EditableComponent>
    
    MapTo(RESOURCE_TYPE)(EditableText);
    
    export default EditableText;
    

可编辑的文本组件实施应如下所示:

可编辑文本组件

图像组件

  1. 在IDE中打开SPA项目

  2. src/components/editable/core/Image.js处创建React组件

  3. 将以下代码添加到Image.js

    code language-javascript
    import React from 'react'
    import { RoutedLink } from "./RoutedLink";
    
    export const imageIsEmpty = (props) => (!props.src) || props.src.trim().length === 0
    
    const ImageInnerContents = (props) => {
    return (<>
        <img src={props.src}
            className={props.baseCssClass + '__image'}
            alt={props.alt} />
        {
            !!(props.title) && <span className={props.baseCssClass + '__title'} itemProp="caption">{props.title}</span>
        }
        {
            props.displayPopupTitle && (!!props.title) && <meta itemProp="caption" content={props.title} />
        }
        </>);
    };
    
    const ImageContents = (props) => {
        if (props.link && props.link.trim().length > 0) {
            return (
            <RoutedLink className={props.baseCssClass + '__link'} isRouted={props.routed} to={props.link}>
                <ImageInnerContents {...props} />
            </RoutedLink>
            )
        }
        return <ImageInnerContents {...props} />
    };
    
    export const Image = (props) => {
        if (!props.baseCssClass) {
            props.baseCssClass = 'cmp-image'
        }
    
        const { isInEditor = false } = props;
        const cssClassName = (isInEditor) ? props.baseCssClass + ' cq-dd-image' : props.baseCssClass;
    
        return (
            <div className={cssClassName}>
                <ImageContents {...props} />
            </div>
        )
    };
    
  4. src/components/editable/EditableImage.js处创建可编辑的React组件

  5. 将以下代码添加到EditableImage.js

import { EditableComponent, MapTo } from '@adobe/aem-react-editable-components';
import { Image, imageIsEmpty } from "./core/Image";
import React from 'react'

import { withConditionalPlaceHolder } from "./core/util/withConditionalPlaceholder";
import { withStandardBaseCssClass } from "./core/util/withStandardBaseCssClass";

const RESOURCE_TYPE = "wknd-app/components/image";

const EditConfig = {
    emptyLabel: "Image",
    isEmpty: imageIsEmpty,
    resourceType: RESOURCE_TYPE
};

const WrappedImage = (props) => {
    const Wrapped = withConditionalPlaceHolder(withStandardBaseCssClass(Image, "cmp-image"), imageIsEmpty, "Image V2");
    return <Wrapped {...props}/>
}

const EditableImage = (props) => <EditableComponent config={EditConfig} {...props}><WrappedImage /></EditableComponent>

MapTo(RESOURCE_TYPE)(EditableImage);

export default EditableImage;
  1. 创建一个SCSS文件src/components/editable/EditableImage.scss,该文件为EditableImage.scss提供自定义样式。 这些样式面向可编辑的React组件的CSS类。

  2. 将以下SCSS添加到EditableImage.scss

    code language-css
    .cmp-image__image {
        margin: 1rem 0;
        width: 100%;
        border: 0;
     }
    
  3. EditableImage.js中导入EditableImage.scss

    code language-javascript
    ...
    import './EditableImage.scss';
    ...
    

可编辑的图像组件实施应如下所示:

可编辑的图像组件

导入可编辑的组件

新创建的EditableTextEditableImage React组件在SPA中引用,并根据AEM返回的JSON动态实例化。 要确保SPA可以使用这些组件,请在Home.js中为其创建import语句

  1. 在IDE中打开SPA项目

  2. 打开文件src/Home.js

  3. 添加AEMTextAEMImage的import语句

    code language-javascript
    ...
    // The following need to be imported, so that MapTo is run for the components
    import EditableText from './editable/EditableText';
    import EditableImage from './editable/EditableImage';
    ...
    

结果应如下所示:

Home.js

如果这些导入是​ 未添加,则SPA不会调用EditableTextEditableImage代码,因此这些组件不会映射到提供的资源类型。

在AEM中配置容器

AEM容器组件使用策略来指定其允许的组件。 使用SPA编辑器时,这是一个关键配置,因为SPA只能呈现已映射AEM组件的SPA组件。 确保仅允许我们为提供的SPA实现的组件:

  • EditableTitle映射到wknd-app/components/title
  • EditableText映射到wknd-app/components/text
  • EditableImage映射到wknd-app/components/image

要配置远程SPA页模板的responsivegrid容器,请执行以下操作:

  1. 登录AEM Author

  2. 导航到​ 工具>常规>模板> WKND应用程序

  3. 编辑​ 报表SPA页面

    响应式网格策略

  4. 在右上角的模式切换器中选择​ 结构

  5. 点击以选择​ 布局容器

  6. 点按弹出栏中的​ 策略 ​图标

    响应式网格策略

  7. 在右侧的​ 允许的组件 ​选项卡下,展开​ WKND应用程序 — 内容

  8. 确保仅选择以下选项:

    • 图像
    • 文本
    • 标题

    远程SPA页

  9. 点按​ 完成

在AEM中创作容器

更新SPA以嵌入<ResponsiveGrid...>、三个可编辑React组件(EditableTitleEditableTextEditableImage)的包装器,以及使用匹配的模板策略更新AEM之后,我们可以开始在容器组件中创作内容。

  1. 登录AEM Author

  2. 导航到​ 站点> WKND应用程序

  3. 点按​ 主页 ​并从顶部操作栏中选择​ 编辑

    • 此时将显示“Hello World”文本组件,因为从AEM项目原型生成项目时,会自动添加此组件
  4. 从页面编辑器右上角的模式选择器中选择​ 编辑

  5. 在标题下方找到​ 布局容器 ​可编辑区域

  6. 打开​ 页面编辑器的侧栏,然后选择​ 组件视图

  7. 将以下组件拖到​ 布局容器 ​中

    • 图像
    • 标题
  8. 将组件拖动以按照以下顺序重新排序:

    1. 标题
    2. 图像
    3. 文本
  9. 作者 标题 ​组件

    1. 点按标题组件,然后点按​ 扳手 ​图标以​ 编辑 ​标题组件

    2. 添加以下文本:

      • 标题: 夏季即将到来,让我们充分利用它!
      • 类型: H1
    3. 点按​ 完成

  10. 作者 图像 ​组件

    1. 在图像组件上,将图像从侧栏拖入(在切换到Assets视图后)
    2. 点按图像组件,然后点按​ 扳手 ​图标以进行编辑
    3. 选中​ 图像是装饰性的 ​复选框
    4. 点按​ 完成
  11. 作者 文本 ​组件

    1. 通过点按文本组件并点按​ 扳手 ​图标来编辑文本组件
    2. 添加以下文本:
      • 现在,您可以享受15%的为期一周的冒险活动和20%的为期两周或更长时间的冒险活动折扣! 在结帐时,添加促销活动代码SUMMERISCOMING以获取折扣!
    3. 点按​ 完成
  12. 组件现已创作,但垂直栈叠。

    已编写的组件

使用AEM布局模式可允许我们调整组件的大小和布局。

  1. 使用右上角的模式选择器切换到​ 布局模式

  2. 调整图像和文本组件的大小,使它们并排显示

    • 图像 ​组件应为​ 8列宽
    • 文本 ​组件应为​ 3列宽

    布局组件

  3. 在AEM页面编辑器中​ 预览 ​您所做的更改

  4. 刷新在http://localhost:3000上本地运行的WKND应用程序以查看所编写的更改!

    SPA中的 容器组件

恭喜!

您已添加一个容器组件,该组件允许作者向WKND应用程序添加可编辑的组件! 您现在知道如何:

  • 在SPA中使用AEM React可编辑组件的ResponsiveGrid组件
  • 创建并注册可编辑的React组件(文本和图像),以便通过容器组件在SPA中使用
  • 配置远程SPA页模板以允许启用SPA的组件
  • 将可编辑组件添加到容器组件
  • SPA编辑器中的创作和布局组件

后续步骤

下一步将使用此相同技术在SPA中将可编辑组件添加到冒险详细信息路由

recommendation-more-help
e25b6834-e87f-4ff3-ba56-4cd16cdfdec4