Edge Delivery Services プロジェクトを使用した WYSIWYG オーサリングのコンテンツモデリング content-modeling

Edge Delivery Servicesプロジェクトでの WYSIWYG オーサリング向けコンテンツモデリングの仕組みと、独自のコンテンツをモデル化する方法について説明します。

前提条件 prerequisites

Edge Delivery Servicesで WYSIWYG オーサリングを使用するプロジェクトは、コンテンツソースや オーサリング方法に関係なく、他のEdge Delivery Servicesプロジェクトの仕組みの大部分を継承します。

プロジェクトのコンテンツをモデル化する前に、まず、次のドキュメントをお読みください。

コンテンツのソースに依存しない方法で機能するような、説得力のあるコンテンツモデルを考え出すには、これらの概念を理解することが不可欠です。このドキュメントでは、特に WYSIWYG オーサリング用に実装された仕組みについて詳しく説明します。

デフォルトコンテンツ default-content

デフォルトコンテンツ ​は、作成者が追加のセマンティックを追加することなく、直感的にページ上に配置されるコンテンツです。これには、テキスト、見出し、リンク、画像が含まれます。そのようなコンテンツは、その機能や目的が一目瞭然です。

AEM では、このコンテンツは非常にシンプルで、事前定義済みのモデルを使用したコンポーネントとして実装され、Markdown や HTML でシリアル化できるすべての機能が含まれます。

  • テキスト:リッチテキスト(リスト要素と、強調文字または斜体文字を含む)
  • タイトル:テキスト、タイプ(h1 - h6)
  • 画像:ソース、説明
  • ボタン:テキスト、タイトル、URL、タイプ(デフォルト、プライマリ、セカンダリ)

これらのコンポーネントのモデルは、Edge Delivery Servicesを使用した WYSIWYG オーサリング用ボイラープレートの一部です。

ブロック blocks

ブロックは、特定のスタイルや機能を使用して豊富なコンテンツを作成するために使用します。デフォルトコンテンツとは異なり、ブロックには追加のセマンティックが必要です。ブロックは、AEM ページエディターのコンポーネントに例えられます。

ブロックは基本的に、JavaScript で装飾され、スタイルシートでスタイル設定されたコンテンツの要素です。

ブロックモデルの定義 model-definition

Edge Delivery Servicesで WYSIWYG オーサリングを使用する場合は、コンテンツを作成するインターフェイスを作成者に提供するために、ブロックのコンテンツを明示的にモデル化する必要があります。 基本的には、モデルを作成して、オーサリング UI がブロックに基づいて作成者に提示するオプションを理解できるようにする必要があります。

component-models.json ファイルは、ブロックのモデルを定義します。コンポーネントモデルで定義されたフィールドは、AEM 内でプロパティとして保持され、ブロックを構成するテーブル内のセルとしてレンダリングされます。

{
  "id": "hero",
  "fields": [
    {
      "component": "reference",
      "valueType": "string",
      "name": "image",
      "label": "Image",
      "multi": false
    },
    {
      "component": "text-input",
      "valueType": "string",
      "name": "imageAlt",
      "label": "Alt",
      "value": ""
    },
    {
      "component": "text-area",
      "name": "text",
      "value": "",
      "label": "Text",
      "valueType": "string"
    }
  ]
}

すべてのブロックにモデルが必要となるわけではありません。一部のブロックは、子のリスト用の単純なコンテナであり、それぞれの子には独自のモデルがあります。

また、ユニバーサルエディターを使用して、どのブロックが存在し、どのブロックをページに追加できるのか定義する必要もあります。component-definitions.json ファイルには、ユニバーサルエディターで使用可能になったコンポーネントの一覧が表示されます。

{
  "title": "Hero",
  "id": "hero",
  "plugins": {
    "xwalk": {
      "page": {
        "resourceType": "core/franklin/components/block/v1/block",
        "template": {
          "name": "Hero",
          "model": "hero"
        }
      }
    }
  }
}

多くのブロックに対して 1 つのモデルを使用できます。例えば、一部のブロックは、テキストと画像を定義するモデルを共有します。

ブロックごとに、開発者は以下を実行します。

  • core/franklin/components/block/v1/block リソースタイプを使用する必要があります。これは、AEM のブロックロジックの汎用実装です。
  • ブロック名を定義する必要があります。ブロック名は、ブロックのテーブルヘッダーにレンダリングされます。
    • ブロック名は、ブロックを修飾する適切なスタイルとスクリプトを取得するために使用します。
  • モデル ID を定義できます。
    • モデル ID は、コンポーネントのモデルへの参照です。作成者がプロパティパネルで使用できるフィールドを定義します。
  • フィルター ID を定義できます。
    • フィルター ID はコンポーネントのフィルターへの参照です。これにより、ブロックやセクションに追加できる子を制限したり、有効にする RTE 機能を制限したりするなど、オーサリング動作を変更できます。

ブロックがページに追加されると、この情報はすべて AEM に保存されます。リソースタイプまたはブロック名のいずれかが見つからない場合、そのブロックはページ上にレンダリングされません。

WARNING
カスタム AEM コンポーネントを実装することは、可能ですが、必須ではなく、推奨もされません。AEM により提供される Edge Delivery Services 用コンポーネントは十分であり、開発を容易にするために一定のガードレールを提供しています。
AEM が提供するコンポーネントは、Edge Delivery Services に公開時に helix-html2md によって、ユニバーサルエディターでページ読み込み時に aem.js によって使用できるマークアップをレンダリングします。マークアップは、AEM とシステムの他の部分との間の安定した契約であり、カスタマイズはできません。このため、プロジェクトではコンポーネントを変更したり、カスタムコンポーネントを使用したりしないでください。

ブロック構造 block-structure

ブロックのプロパティは、コンポーネントモデルで定義され、AEM ではそのまま保持されます。プロパティは、ブロックのテーブルに似た構造内のセルとしてレンダリングされます。

シンプルなブロック simple

最もシンプルな形式では、ブロックは各プロパティを 1 行または 1 列に、モデル内でプロパティが定義されている順序でレンダリングします。

次の例では、モデル内で最初に画像を定義し、その次にテキストを定義しています。したがって、最初に画像、2 番目にテキストでレンダリングされます。

データ
code language-json
{
  "name": "Hero",
  "model": "hero",
  "image": "/content/dam/image.png",
  "imageAlt": "Helix - a shape like a corkscrew",
  "text": "<h1>Welcome to AEM</h1>"
}
マークアップ
code language-html
<div class="hero">
  <div>
    <div>
      <picture>
        <img src="/content/dam/image.png" alt="Helix - a shape like a corkscrew">
      </picture>
    </div>
  </div>
  <div>
    <div>
      <h1>Welcome to AEM</h1>
    </div>
  </div>
</div>
テーブル
code language-text
+---------------------------------------------+
| Hero                                        |
+=============================================+
| ![Helix - a shape like a corkscrew][image0] |
+---------------------------------------------+
| # Welcome to AEM                            |
+---------------------------------------------+

一部のタイプの値はマークアップ内のセマンティックを推定でき、プロパティは単一のセルに結合されます。この動作については、型推論の節で説明します。

キーと値のブロック key-value

多くの場合、レンダリングされたセマンティックマークアップの修飾、CSS クラス名の追加、新しいノードの追加、DOM 内での移動、スタイルの適用をお勧めします。

ただし、その他の場合は、ブロックはキー値ペアのような設定として読み取られます。

この例として、 セクションのメタデータがあります。 この使用例では、ブロックをキー値ペアテーブルとしてレンダリングするように設定できます。詳しくは、セクションとセクションのメタデータの節を参照してください。

データ
code language-json
{
  "name": "Featured Articles",
  "model": "spreadsheet-input",
  "key-value": true,
  "source": "/content/site/articles.json",
  "keywords": ['Developer','Courses'],
  "limit": 4
}
マークアップ
code language-html
<div class="featured-articles">
  <div>
    <div>source</div>
    <div><a href="/content/site/articles.json">/content/site/articles.json</a></div>
  </div>
  <div>
    <div>keywords</div>
    <div>Developer,Courses</div>
  <div>
  <div>
    <div>limit</div>
    <div>4</div>
  </div>
</div>
テーブル
code language-text
+-----------------------------------------------------------------------+
| Featured Articles                                                     |
+=======================================================================+
| source   | [/content/site/articles.json](/content/site/articles.json) |
+-----------------------------------------------------------------------+
| keywords | Developer,Courses                                          |
+-----------------------------------------------------------------------+
| limit    | 4                                                          |
+-----------------------------------------------------------------------+

コンテナブロック container

前述の構造は両方とも、プロパティのリストという 1 つの次元を持ちます。コンテナブロックを使用すると、子(通常は、同じタイプまたはモデル)を追加できるので、2 次元になります。これらのブロックは、最初に 1 つの列を持つ行としてレンダリングされる独自のプロパティを引き続きサポートします。また、子も追加できます。この場合、各項目は行としてレンダリングされ、各プロパティはその行内の列としてレンダリングされます。

次の例では、ブロックは、リンクされたアイコンのリストを子として受け入れます。それぞれのリンクされたアイコンには、画像とリンクが含まれています。フィルター設定を参照するために、ブロックのデータにフィルター ID が設定される点に注意してください。

データ
code language-json
{
  "name": "Our Partners",
  "model": "text-only",
  "filter": "our-partners",
  "text": "<p>Our community of partners is ...</p>",
  "item_0": {
    "model": "linked-icon",
    "image": "/content/dam/partners/foo.png",
    "imageAlt": "Icon of Foo",
    "link": "https://foo.com/"
  },
  "item_1": {
    "model": "linked-icon"
    "image": "/content/dam/partners/bar.png",
    "imageAlt": "Icon of Bar",
    "link": "https://bar.com"
  }
}
マークアップ
code language-html
<div class="our-partners">
  <div>
    <div>
        Our community of partners is ...
    </div>
  </div>
  <div>
    <div>
      <picture>
         <img src="/content/dam/partners/foo.png" alt="Icon of Foo">
      </picture>
    </div>
    <div>
      <a href="https://foo.com">https://foo.com</a>
    </div>
  </div>
  <div>
    <div>
      <picture>
         <img src="/content/dam/partners/bar.png" alt="Icon of Bar">
      </picture>
    </div>
    <div>
      <a href="https://bar.com">https://bar.com</a>
    </div>
  </div>
</div>
テーブル
code language-text
+------------------------------------------------------------ +
| Our Partners                                                |
+=============================================================+
| Our community of partners is ...                            |
+-------------------------------------------------------------+
| ![Icon of Foo][image0] | [https://foo.com](https://foo.com) |
+-------------------------------------------------------------+
| ![Icon of Bar][image1] | [https://bar.com](https://bar.com) |
+-------------------------------------------------------------+

ブロックのセマンティックコンテンツモデルの作成 creating-content-models

ブロック構造の仕組みがわかれば、AEMで 1 対 1 で保持されるコンテンツを配信層にマッピングするコンテンツモデルを作成できます。

どのプロジェクトでも初期段階で、すべてのブロックについて、コンテンツモデルを慎重に検討する必要があります。作成者がブロックの実装やスタイルを再利用しながら、切り替えたり組み合わせたりできるようにするには、コンテンツソースやオーサリングエクスペリエンスに依存しないようにする必要があります。詳細と一般的なガイダンスについては、David のモデル(テイク 2)にあります。具体的には、ブロックコレクションは、一般的なユーザーインターフェイスのパターンにおける特定の使用例に対応する、広範なコンテンツモデルのセットを含んでいます。

Edge Delivery Servicesを使用した WYSIWYG オーサリングでは、リッチテキストのような文脈依存マークアップを編集するのではなく、複数のフィールドで構成されるフォームで情報を作成する場合に、魅力的なセマンティックコンテンツモデルを提供する方法が問題になります。

この問題を解決するには、魅力的なコンテンツモデルを容易に作成できる 3 つの方法があります。

NOTE
ブロック実装は、コンテンツを分解し、ブロックをクライアント側でレンダリングされた DOM に置き換えることができます。これは、開発者にとっては可能であり、直感的ですが、Edge Delivery Services にはベストプラクティスではありません。

型推論 type-inference

一部の値については、値自体からセマンティックの意味を推測できます。次のような値が含まれます。

  • 画像 - AEM のリソースへの参照が image/ で始まる MIME タイプのアセットである場合、その参照は <picture><img src="${reference}"></picture> としてレンダリングされます。
  • リンク - AEM 内に存在している参照が画像ではない場合、または値が https?:// または # で始まる場合、参照は <a href="${reference}">${reference}</a> としてレンダリングされます。
  • リッチテキスト - トリミングされた値が段落(pulolh1 - h6 など)で始まる場合、値はリッチテキストとしてレンダリングされます。
  • クラス名 - classes プロパティはブロックオプションとして扱われ、単純なブロックではテーブルヘッダーにレンダリングされ、またはコンテナブロック内にある項目の値リストとしてレンダリングされます。 ブロックを別のスタイルに設定する際、完全に新しいブロックを作成する必要はない場合に役立ちます。
  • 値リスト - 値が複数値プロパティで、最初の値が以前の値でない場合、すべての値がコンマ区切りリストとして連結されます。

それ以外の部分はすべてプレーンテキストとしてレンダリングされます。

フィールドの折りたたみ field-collapse

フィールドの折りたたみは、サフィックスの TitleTypeMimeTypeAltText(すべて大文字と小文字を区別)を使用する命名規則に基づいて、複数のフィールド値を 1 つのセマンティック要素に組み合わせるメカニズムです。これらのサフィックスで終わるプロパティは、値と見なされず、別のプロパティの属性と見なされます。

画像 image-collapse
データ
code language-json
{
  "image": "/content/dam/red-car.png",
  "imageAlt: "A red card on a road"
}
マークアップ
code language-html
<picture>
  <img src="/content/dam/red-car.png" alt="A red car on a road">
</picture>
テーブル
code language-text
![A red car on a road][image0]
データ
code language-json
{
  "link": "https://www.adobe.com",
  "linkTitle": "Navigate to adobe.com",
  "linkText": "adobe.com",
  "linkType": "primary"
}
マークアップ

linkType なし、または linkType=default

code language-html
<a href="https://www.adobe.com" title="Navigate to adobe.com">adobe.com</a>

linkType=primary

code language-html
<strong>
  <a href="https://www.adobe.com" title="Navigate to adobe.com">adobe.com</a>
</strong>

linkType=secondary

code language-html
<em>
  <a href="https://www.adobe.com" title="Navigate to adobe.com">adobe.com</a>
</em>
テーブル
code language-text
[adobe.com](https://www.adobe.com "Navigate to adobe.com")
**[adobe.com](https://www.adobe.com "Navigate to adobe.com")**
_[adobe.com](https://www.adobe.com "Navigate to adobe.com")_
見出し headings-collapse
データ
code language-json
{
  "heading": "Getting started",
  "headingType": "h2"
}
マークアップ
code language-html
<h2>Getting started</h2>
テーブル
code language-text
## Getting started

要素のグループ化 element-grouping

フィールドの折りたたみは、複数のプロパティを単一のセマンティック要素に組み合わせることですが、要素のグループ化とは、複数のセマンティック要素を 1 つのセルに連結することです。これは、作成者が作成できる要素のタイプと数を制限する必要がある使用例で特に役立ちます。

例えば、ティーザーコンポーネントを使用すると、作成者は、サブタイトル、タイトル、最大 2 つのコールトゥアクションボタンと組み合わせた 1 つの段落の説明のみを作成できます。これらの要素をグループ化すると、セマンティックマークアップが生成され、追加の操作を行わずにスタイルを設定できます。

要素のグループ化では、グループ名がグループ内の各プロパティからアンダースコアで区切られる命名規則が使用されます。グループ内のプロパティのフィールドの折りたたみは、前述のように機能します。

データ
code language-json
{
  "name": "teaser",
  "model": "teaser",
  "image": "/content/dam/teaser-background.png",
  "imageAlt": "A group of people sitting on a stage",
  "teaserText_subtitle": "Adobe Experience Cloud"
  "teaserText_title": "Meet the Experts"
  "teaserText_titleType": "h2"
  "teaserText_description": "<p>Join us in this ask me everything session...</p>"
  "teaserText_cta1": "https://link.to/more-details",
  "teaserText_cta1Text": "More Details"
  "teaserText_cta2": "https://link.to/sign-up",
  "teaserText_cta2Text": "RSVP",
  "teaserText_cta2Type": "primary"
}
マークアップ
code language-html
<div class="teaser">
  <div>
    <div>
      <picture>
        <img src="/content/dam/teaser-background.png" alt="A group of people sitting on a stage">
      </picture>
    </div>
  </div>
  <div>
    <div>
      <p>Adobe Experience Cloud</p>
      <h2>Meet the Experts</h2>
      <p>Join us in this ask me everything session ...</p>
      <p><a href="https://link.to/more-details">More Details</a></p>
      <p><strong><a href="https://link.to/sign-up">RSVP</a></strong></p>
    </div>
  </div>
</div>
テーブル
code language-text
+-------------------------------------------------+
| Teaser                                          |
+=================================================+
| ![A group of people sitting on a stage][image0] |
+-------------------------------------------------+
| Adobe Experience Cloud                          |
| ## Welcome to AEM                               |
| Join us in this ask me everything session ...   |
| [More Details](https://link.to/more-details)    |
| [RSVP](https://link.to/sign-up)                 |
+-------------------------------------------------+

セクションとセクションのメタデータ sections-metadata

開発者は複数のブロックを定義およびモデル化するのと同じ方法で、異なるセクションを定義できます。

Edge 配信サービスのコンテンツモデルでは、セクションに含まれるデフォルトのコンテンツまたはブロックである1 レベルのネストのみを意図的に許可します。つまり、他のコンポーネントを含む、より複雑なビジュアルコンポーネントを持つには、セクションとしてモデル化し、自動ブロッククライアント側を使用して組み合わせる必要があります。これの一般的な例としては、タブや、アコーディオンのような折りたたみ可能なセクションがあります。

セクションは、ブロックと同じ方法で定義できますが、リソースタイプは core/franklin/components/section/v1/section となります。セクションには、ユニバーサルエディターのみにより使用される名前とフィルター ID を指定できます。また、セクションには、セクションのメタデータをレンダリングするのに使用されるモデル ID も指定できます。モデルはこのようにして、セクションメタデータブロックのモデルとなります。空でない場合、このモデルは自動的にキーと値のブロックとしてセクションに追加されます。

デフォルトのセクションのモデル ID およびフィルター IDsection です。これを使用して、デフォルトのセクションの動作を変更できます。次の使用例は、いくつかのスタイルと背景画像をセクションメタデータモデルに追加します。

{
  "id": "section",
  "fields": [
    {
      "component": "multiselect",
      "name": "style",
      "value": "",
      "label": "Style",
      "valueType": "string",
      "options": [
        {
          "name": "Fade in Background",
          "value": "fade-in"
        },
        {
          "name": "Highlight",
          "value": "highlight"
        }
      ]
    },
    {
      "component": "reference",
      "valueType": "string",
      "name": "background",
      "label": "Image",
      "multi": false
    }
  ]
}

次の例では、タブセクションを定義します。これを使用すると、自動ブロック中にタブタイトルデータ属性を持つ連続セクションをタブブロックに結合して、タブブロックを作成できます。

{
  "title": "Tab",
  "id": "tab",
  "plugins": {
    "xwalk": {
      "page": {
        "resourceType": "core/franklin/components/section/v1/section",
        "template": {
          "name": "Tab",
          "model": "tab",
          "filter": "section"
        }
      }
    }
  }
}

ページメタデータ page-metadata

ドキュメントには、ページの <head> でどの <meta> 要素がレンダリングされるかを定義するのに使用されるページメタデータブロックを含めることができます。AEM as a Cloud Service のページのプロパティは、titledescriptionkeywords などの Edge 配信サービスですぐに使用できるプロパティにマッピングされます。

独自のメタデータの定義方法を詳しく学ぶ前に、次のドキュメントを参照して、最初にページメタデータの概念を理解してください。

追加のページメタデータを 2 つの方法で定義することもできます。

メタデータスプレッドシート metadata-spreadsheets

AEM as a Cloud Service では、パスごとまたはパスパターンごとにテーブルのような方法でメタデータを定義できます。Excel や Google スプレッドシートに似た、表のようなデータ用のオーサリング UI が利用可能です。

このようなテーブルを作成するには、ページを作成し、サイトコンソールのメタデータテンプレートを使用します。

スプレッドシートのページプロパティで、必要なメタデータフィールドと URL を定義します。次に、ページパスまたはページパスパターンごとにメタデータを追加します。

公開する前に、パスマッピングにもスプレッドシートが追加されていることを確認してください。

{
  "mappings": [
    "/content/site/:/",
    "/content/site/metadata:/metadata.json"
  ]
}

ページプロパティ page-properties

AEM で使用できるデフォルトのページプロパティの多くは、ドキュメント内の各ページのメタデータにマッピングされます。これには、titledescriptionrobotscanonical url または keywords などが含まれます。次の AEM 固有のプロパティもいくつか使用できます。

  • ISO8601 形式の modified-time としての cq:lastModified
  • ISO8601 形式の published-time としてドキュメントが最後に公開された時刻
  • cq-tags としての cq:tags、タグ ID のコンマ区切りリスト。

また、カスタムページメタデータのコンポーネントモデルを定義することもできます。このモデルは、AEM Sites のページのプロパティダイアログのタブとして作成者が使用できます。

これを行うには、ID page-metadata を持つコンポーネントモデルを作成します。

{
  "id": "page-metadata",
  "fields": [
    {
      "component": "text",
      "name": "theme",
      "label": "Theme"
    }
  ]
}

次の手順 next-steps

これで、コンテンツのモデル化方法を理解できたので、WYSIWYG オーサリングプロジェクトを使用して独自のEdge Delivery Services用のブロックを作成できます。

Edge Delivery Servicesプロジェクトで WYSIWYG オーサリングを使用して、ユニバーサルエディターで使用するために実装されたブロックを作成する方法については 🔗 ユニバーサルエディターで使用するために実装されたブロックの作成 ドキュメントを参照してください。

Edge Delivery Servicesとコンテンツオーサリング用ユニバーサルエディターを使用した新しいAdobe Experience Manager サイトの導入については、ドキュメント Edge Delivery Servicesを使用した WYSIWYG オーサリングの開発者向けガイドを参照してください。

TIP
AEM as a Cloud Serviceをコンテンツソースとする WYSIWYG オーサリングが可能な新しいEdge Delivery Servicesプロジェクトの作成に関するエンドツーエンドのチュートリアルについては、 このAEM GEMs ウェビナーを参照してください。
recommendation-more-help
fbcff2a9-b6fe-4574-b04a-21e75df764ab