可編輯的容器元件

固定元件 為編寫SPA內容提供一些靈活性,但這種方法很嚴格,並且要求開發人員定義可編輯內容的確切構成。 為了支援作者建立卓越的體驗,SPA編輯器支援在SPA中使用容器元件。 容器元件可讓作者將允許的元件拖放至容器中並加以撰寫,就像在傳統AEM Sites製作中一樣!

可編輯的容器元件

在本章中,我們將可編輯的容器新增至首頁檢視,讓作者可直接在SPA中使用可編輯的React元件來撰寫和配置豐富的內容體驗。

更新WKND應用程式

若要將容器元件新增至「首頁」檢視:

  • 匯入AEM React Editable元件的 ResponsiveGrid 元件
  • 匯入並註冊自訂的可編輯React元件(文字和影像),以用於ResponsiveGrid元件

使用ResponsiveGrid元件

若要將可編輯區域新增至「首頁」檢視:

  1. 開啟並編輯 react-app/src/components/Home.js

  2. 匯入 ResponsiveGrid 元件來源 @adobe/aem-react-editable-components 並將其新增至 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 將對應至 responsivegrid 節點定義於 Remote SPA Page AEM範本,並會在以下專案建立的新AEM頁面上自動建立: Remote SPA Page 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編輯器中提供的彈性撰寫體驗容器的效果。 我們已建立可編輯的Title元件,但接下來讓我們介紹幾個專案,讓作者可在新新增的ResponsiveGrid元件中使用可編輯的文字和影像元件。

新的可編輯文字和影像React元件是使用中說明的可編輯元件定義模式所建立。 可編輯的固定元件.

可編輯文字元件

  1. 在IDE中開啟SPA專案

  2. 在建立React元件 src/components/editable/core/Text.js

  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. 於建立可編輯的React元件 src/components/editable/EditableText.js

  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. 在建立React元件 src/components/editable/core/Image.js

  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. 於建立可編輯的React元件 src/components/editable/EditableImage.js

  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.scssEditableImage.js

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

可編輯的影像元件實作應如下所示:

可編輯的影像元件

匯入可編輯的元件

新建立的 EditableTextEditableImage React元件在SPA中參照,並根據AEM傳回的JSON動態具現化。 為確保這些元件可供SPA使用,請在中為它們建立匯入陳述式 Home.js

  1. 在IDE中開啟SPA專案

  2. 開啟檔案 src/Home.js

  3. 新增匯入陳述式 AEMTextAEMImage

    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

如果這些匯入為 已新增, EditableTextEditableImage SPA不會叫用程式碼,因此元件不會對應至提供的資源型別。

在AEM中設定容器

AEM容器元件會使用原則來指定其允許的元件。 這是使用SPA編輯器時的關鍵設定,因為SPA只能轉譯對應了SPA元件的AEM元件。 請確定僅允許我們提供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元件的包裝函式(EditableTitleEditableText、和 EditableImage)且AEM已更新相符的範本原則,我們就能開始在容器元件中編寫內容。

  1. 登入AEM Author

  2. 瀏覽至 Sites > WKND應用程式

  3. 點選 首頁 並選取 編輯 從頂端動作列

    • 「Hello World」文字元件隨即顯示,因為從AEM專案原型產生專案時會自動新增此元件
  4. 選取 編輯 從「頁面編輯器」右上角的模式選取器

  5. 找到 配置容器 標題下方的可編輯區域

  6. 開啟 頁面編輯器側欄,然後選取 元件檢視

  7. 將下列元件拖曳至 配置容器

    • 影像
    • 標題
  8. 拖曳元件以將其重新排序為下列順序:

    1. 標題
    2. 影像
    3. 文字
  9. 作者標題 元件

    1. 點選「標題」元件,然後點選 扳手 圖示至 編輯 標題元件

    2. 新增下列文字:

      • 標題: 夏天就要來了,讓我們好好利用吧!
      • 型別: H1
    3. 點選 完成

  10. 作者影像 元件

    1. 在「影像」元件上,從側邊欄(切換至「資產」檢視後)將影像拖曳到中
    2. 點選影像元件,然後點選 扳手 圖示以編輯
    3. 檢查 影像為裝飾性 核取方塊
    4. 點選 完成
  11. 作者文字 元件

    1. 點選「文字」元件,然後點選 扳手 圖示
    2. 新增下列文字:
      • 現在,您可以在所有的一週冒險中獲得15%,在所有兩週或更長時間的冒險中獲得20%! 結帳時,新增行銷活動代碼SUMMERISCOMING以取得折扣!
    3. 點選 完成
  12. 您的元件現在已製作,但可垂直棧疊。

    編寫的元件

使用AEM配置模式可讓我們調整元件的大小和配置。

  1. 切換至 版面模式 使用右上方的模式選取器

  2. 調整大小 影像和文字元件,使它們並排

    • 影像 元件應為 8欄寬
    • 文字 元件應為 3欄寬

    配置元件

  3. 預覽 您在AEM頁面編輯器中進行的變更

  4. 重新整理在本機執行的WKND應用程式 http://localhost:3000 以檢視編寫的變更!

    SPA中的容器元件

恭喜!

您已新增容器元件,讓作者可將可編輯的元件新增到WKND應用程式! 您現在知道如何:

  • 使用AEM React Editable元件的 ResponsiveGrid SPA中的元件
  • 建立並註冊可編輯的React元件(文字和影像),以透過容器元件用於SPA
  • 設定遠端SPA頁面範本,以允許啟用SPA的元件
  • 將可編輯的元件新增至容器元件
  • 在SPA編輯器中製作和配置元件

後續步驟

下一個步驟會使用此相同技術來 將可編輯的元件新增至「冒險詳細資訊」路由 在SPA中。

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