AEM Sitesのコンポーネントマッピング
この記事では、(複合コンポーネントマッピングを使用して)AEM サイトのコンポーネントマッピングのさまざまな側面について説明します。
コンポーネントマッピングルール
HTMLをコンポーネントに変換するには、ルールのJSON配列(componentmapping.json)を使用します。 ルールはできるだけシンプルかつ明示的で、具体的なものにする必要があります。
HTML要素とそのクラスをターゲットにする
-
HTML タグ名を
nameに書き込みます。 -
クラスが存在する場合、その要素に適用されたCSS クラスを
classに含めます。
例:code language-html <div class ="sample-class"> <p> Sample html element </p> </div>code language-json { "name": "div", "class": "sample-class", "resourceType": "guides-components/components/table", "attributeMap": [] }
上記の要素を定義する際は、次の点を確認してください。
nameはコンマ区切りのリストにできます(例:"h1, h2")。classは要素に存在する必要があります(リストされているすべてのクラスが一致する必要があります)。resourceTypeは、tableコンポーネントを使用する予定であることを示します。guides-componentsパッケージは、Guidesが提供するOOTBです。 必要に応じて、core/wcm/などの他のコンポーネントパッケージも使用できます。
attributeMapを使用してJCR ノードにプロパティを保存する
出力ノードにプロパティを設定するには、attributeMapにエントリを追加します。 各エントリはattrs[to] = valueを生成します。
共通パターン:
// copy an attribute
{ "attribute": "src", "to": "image-src" }
// read content or tag name
{ "from": "textContent", "to": "jcr:title" }
{ "from": "outerHTML", "to": "text" }
{ "from": "innerHTML", "to": "text" }
{ "from": "name", "to": "type" } // the tag name, e.g., "h2"
// constant value
{ "value": true, "to": "textIsRich" }
次に、HTMLからJSONへの画像エレメントの例を示します。
<img src="/content/dam/aemg-docs/tragopan.svg" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt="">
{
"name": "img",
"resourceType": "core/wcm/components/image/v2/image",
"attributeMap": [
{
"from": "src",
"to": "fileReference"
},
{
"value": ["fileReference"],
"to": "path-attributes"
}
]
}
専用エントリを使用したパスの正規化
値を正規化(絶対化)する場合は、次を使用してどの属性キーを正規化するかを宣言します。
{
"value": ["text"],
"to": "path-attributes"
}
次の重要な点に注意してください。
valueで正規化するプロパティ名のリストを入力します(例:["text"]または["href", "src"])。- 最終的なコンポーネントを構築する際に、これらのプロパティ名の下にある値が正規化されます。
コンポーネントに分割する前にHTML値を抽出する
ドキュメントを個別のコンポーネントに分割する前に、fromを使用してエレメントから値を読み取る方法を指定します。
"textContent":要素のプレーンテキスト"outerHTML":要素とその内部マークアップ"innerHTML":要素の内部マークアップのみ- その他の文字列:属性名として扱われます(例:
"src"、"href")。
例:
{ "from": "textContent", "to": "jcr:title" }
{ "from": "outerHTML", "to": "text" }
{ "from": "innerHTML", "to": "snippet" }
{ "from": "src", "to": "image#src" }
componentmapping.jsonの最小エンドツーエンドの例
[
{
"name": "h1, h2",
"class": "topic-title",
"resourceType": "core/wcm/components/title/v2/title",
"attributeMap": [
{ "from": "textContent", "to": "text" },
{ "from": "name", "to": "type" }
]
},
{
"name": "img",
"class": "hero",
"resourceType": "weretail/components/content/heroimage",
"attributeMap": [
{ "from": "src", "to": "image#src" },
{ "value": ["image#src"], "to": "path-attributes" }
]
},
{
"name": "#element",
"resourceType": "core/wcm/components/text/v2/text",
"attributeMap": [
{ "from": "outerHTML", "to": "text" },
{ "value": true, "to": "textIsRich" }
]
}
]
ターゲットとする要素とクラスを定義し、attributeMapを使用してノードプロパティを設定し、path-attributes エントリを追加してパスを正規化し、抽出する値に対して適切なfromを選択します。 上記のheroimageはwe-retail サイトのコンポーネントです。
メモ:デフォルトのリッチテキストについて説明し、そのリッチテキストが使用される要素を特定することが重要です。
カスタムコンポーネントの作成
セル内に画像を表示するカスタムテーブルコンポーネントを作成する方法について説明します。 このアプローチにより、動的なコンテンツを実現する際に、クリーンで再利用可能なデザインを実現できます。 構築する要素、その理由、主要な前提条件、高度なデザインなどについて説明します。
構築する要素
HTML テーブルの内容を受け入れ、その中のすべての<img>をAEM Core Image コンポーネントの出力に置き換えるカスタムテーブルコンポーネント。 これにより、テーブルのマークアップを完全に制御しながら、コア画像の機能(レスポンシブ画像、alt処理、アクセシビリティ)を再利用できます。
この方法を使用すると、AEM サイト用の他のカスタムコンポーネントを構築できます(複合コンポーネントマッピングを使用)。
このアプローチの理由
- 再利用: コア画像の再実装ではなく、成熟した動作を活用します。
- 一貫性:テーブル内の画像は、サイト上の他の場所の画像と同じように動作します。
- サーバーサイド:画像は、パフォーマンス、SEO、アクセシビリティのために、サーバー上でレンダリングされます。
前提条件
- AEM SDKが実行中で、このプロジェクトはチェックアウトされました。
- AEM インスタンスにインストールされたコアコンポーネント。
- Mavenを利用できます。
高度なデザイン
- オーサーは、コンポーネントダイアログのテーブルにHTMLを提供します。
- Sling モデルは、HTMLを解析し、
<img>タグを見つけ、各イメージに対して、Core Image コンポーネントをサーバーサイドでレンダリングするサービスを呼び出します。 - モデルは、元の
<img>をキャプチャしたCore Image HTMLと交換し、完成したHTMLをHTLに渡して出力します。
テーブルは1回出力され、既にコア画像マークアップが含まれています。 クライアントサイドのDOM操作は必要ありません。
フォルダー構造とキーファイル(このリポジトリ内)
-
コンポーネント HTLおよびclientlibs:
ui.apps/src/main/content/jcr_root/apps/guides-components/components/table/table.html(HTL レンダラー)_cq_editConfig.xml(リスナーを更新)clientlibs/(css.txt、js.txt、css/table.css、js/table.js)
-
Sling モデル:
core/src/main/java/com/adobe/guides/aem/components/core/models/TableModel.java -
画像レンダリングサービス:
core/src/main/java/com/adobe/guides/aem/components/core/services/ImageComponentRenderer.java
実装の手順
テーブルコンポーネント(コンポーネントノード)を定義
apps/guides-components/components/tableの下にコンポーネントを作成します。 まだ持っていない場合は、サイドパネルに登録するために、以下のように最小値の.content.xmlを追加します。
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Component"
jcr:title="Table"
componentGroup="Guides - Custom"/>
作成者がページに追加できるコンポーネントであることをAEMに示します。
HTLでレンダリングし、スタイルを含める
Sling モデルを使用して、処理されたHTMLを出力します。 CSS/JS用にclientlib カテゴリを含めます。
<sly data-sly-use.model="com.adobe.guides.aem.components.core.models.TableModel"
data-sly-use.clientLib="/libs/granite/sightly/templates/clientlib.html">
</sly>
<sly data-sly-call="${clientLib.css @ categories='guides-components.table'}"></sly>
<sly data-sly-test="${wcmmode.edit && !model.hasContent}">
<div class="cq-placeholder" data-emptytext="${component.title}"></div>
</sly>
<div data-sly-test="${model.hasContent}"
class="gu-table-wrapper ${model.enableResponsive ? 'gu-table--responsive' : ''} gu-table--style-${model.tableStyle}"
id="${model.componentId}">
${model.processedTableHtml @ context='unsafe'}
</div>
このモデルは、既にレンダリングされたCore Imageを含む完全なHTMLを返すため、HTLはそれを印刷するだけです。
Sling モデルを追加してHTMLを処理し、Core Imageをレンダリングします
モデルは、ダイアログフィールドを読み取り、テーブル HTMLを解析し、各<img>を見つけ、サービスを介してCore Image HTMLに置き換えます。
TableModelの重要なノウハウを以下に示します。
- リソースのプロパティから
tableHtml、enableResponsive、tableStyleを読み取ります。 - Jsoupを使用して、HTMLを安全に解析および編集します。
ImageComponentRendererを呼び出して、コア画像をレンダリングし、HTMLをキャプチャします。- 元の
<img>からCSS クラスとスタイルを保持します。 - DAM パスを正規化します(
/jcr:content/renditions/*を削除)。
@Model(adaptables = {Resource.class, SlingHttpServletRequest.class},
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class TableModel {
@ValueMapValue private String tableHtml;
@ValueMapValue private boolean enableResponsive;
@ValueMapValue private String tableStyle;
@OSGiService private ImageComponentRenderer imageRenderer;
// ...
@PostConstruct
protected void init() {
// parse HTML, for each <img> build image props (fileReference, alt, title)
// call imageRenderer.renderImageComponent(...)
// replace <img> with returned Core Image HTML
}
public String getProcessedTableHtml() { /* return final HTML */ }
}
これにより、サーバー上のロジックが一元化され、コアイメージの動作が再利用されます。
サービス経由でコアイメージをレンダリングする(サーバーサイドのインクルード)
ImageComponentRendererはコア画像コンポーネントをレンダリングし、出力をキャプチャします。 It
core/wcm/components/image/v2/imageを強制するリソースをラップします。- は、
RequestDispatcher#includeを使用してレンダリングします。 - 応答を文字列として取得します。
@Component(service = ImageComponentRenderer.class)
public class ImageComponentRenderer {
private static final String IMAGE_RESOURCE_TYPE = "core/wcm/components/image/v2/image";
public String renderImageComponent(Resource base, Map<String,Object> props,
SlingHttpServletRequest req, SlingHttpServletResponse resp) {
// create wrapped resource with IMAGE_RESOURCE_TYPE and props
// dispatcher.include(...) with a response wrapper to capture HTML
// return captured HTML
}
}
これにより、子コンポーネントとしてだけでなく、必要な場所に コアイメージをドロップできます。
クライアントライブラリ
小さなスタイルまたは将来のJS用にclientlibを作成します。 上記のHTLは、guides-components.table カテゴリを読み込みます。
clientlibs/css.txt
#base=css
table.css
clientlibs/js.txt
#base=js
table.js
これにより、スタイル/スクリプトがモジュール化され、見つけやすくなります。
ダイアログフィールド (作成者入力)
少なくとも次のプロパティを含むダイアログを追加します。
- テーブル HTML:
./tableHtml(textarea); テーブルのHTML。 - レスポンシブを有効にする:
./enableResponsive(チェックボックス)。レスポンシブラッパークラスを切り替えます。 - 表スタイル:
./tableStyle(選択)。スタイル修飾子クラスを適用します。
これらのマップ 1:1は、Sling モデルのプロパティと制御レンダリングにマッピングされます。
テンプレートのコンポーネントを許可
テンプレートエディターで、レイアウトコンテナポリシー/許可されたコンポーネント/テーブルコンポーネントを ガイド – カスタム の下で有効にするを編集します。
作成者は、ポリシーで許可されるまでコンポーネントを追加できません。
オーサリングのヒント
- テーブルに有効なHTMLを貼り付けます。 モデルは画像URLをサニタイズおよび調整します。
- 画像にはDAM アセットパスを使用します。レンディションは元のアセットパスに正規化されます。
- 可能な場合は、HTMLに代替テキストを入力します。それ以外の場合は、画像に装飾的なマークが付けられます。
制約
- Core Image v2を提供しています。 バージョンを切り替えるには、
IMAGE_RESOURCE_TYPEを更新してください。 - 合成レンダリングの場合、モデルはCore Imageで生成された
.coreimg.個のURLを直接DAM パスに置き換え、壊れたURLを避けるためにsrcset個を削除します。 - すべてのレンダリングは、サーバー上で1回実行されます。JavaScriptはオプションです。
クイックリファレンス(実装)
- HTML:
ui.apps/.../components/table/table.html - Clientlibs:
ui.apps/.../components/table/clientlibs/ - モデル:
core/.../models/TableModel.java - サービス:
core/.../services/ImageComponentRenderer.java
このパターンでは、コアコンポーネントをサーバーサイドで作成し、コアロジックを再利用しながらマークアップを維持する方法を示します。