Adobe Target RecommendationsのDesign記法について(基本編)

Adobe Target ではA/Bテストやパーソナライゼーション機能に加えて、レコメンデーション機能もあります。(Premium 契約が必要ですが)

[Adobe TargetRecommendations | Adobe Target](https://experienceleague.adobe.com/docs/target/using/recommendations/recommendations.html?lang=ja)

レコメンデーション機能を使うにあたって、必要な設定の一つであるレコメンデーションが入ったオファーを作るためのDesign(HTMLなど) を設定する為の記法についてまとめてみました。

## Design の基本的な書き方

基本的にはヘルプに色々と説明が書いてあります。が…非常に量が多いので、かいつまんで説明をしていきますね。とりあえずWeb(HTML)を使った場合を想定してまずは話しします。


### その1. マーキング文字を入れて埋めていく

一番シンプルなのはAdobe Targetがレコメンデーション情報を入れる為のマーキング文字を埋めていく方法です。マーキング文字はこんな感じで書きます。

>マーキング文字
"$entity{対象レコメンド番目}.{商品Entityキー}"
対象レコメンド番目 = 返却されるレコメンド何番目か？

具体的に言うとこんな形の書き方へ

- $entity1.id → レコメンド商品1番目の商品ID(entity.key)
- $entity2.attr1 → レコメンド商品2番目のカスタムEntity "attr1" の値

これを使ってHTMLを書くので例えば…

```html
<div>
   <ul>
     <!-- 1商品目 -->
     <li>商品名: $entity1.name <span class="sku">($entity1.id)</span></li>
     <li>商品カテゴリ: $entity1.maincategory > $entity1.subcategory </li>
     <li>価格: <span class="price"> $entity1.price 円</span></li>
     <li><img class="item_image" src="$entity1.thumbnailUrl" /></li>
   </ul>
   <ul>
     <!-- 2商品目 -->
     <li>商品名: $entity2.name <span class="sku">($entity2.id)</span></li>
     <li>商品カテゴリ: $entity2.maincategory > $entity2.subcategory </li>
     <li>価格: <span class="price"> $entity2.price 円</span></li>
     <li><img class="item_image" src="$entity2.thumbnailUrl" /></li>
   </ul>
   <ul>
     <!-- 3商品目 -->
     <li>商品名: $entity3.name <span class="sku">($entity3.id)</span></li>
     <li>商品カテゴリ: $entity3.maincategory > $entity3.subcategory </li>
     <li>価格: <span class="price"> $entity3.price 円</span></li>
     <li><img class="item_image" src="$entity3.thumbnailUrl" /></li>
   </ul>
</div>
```

この様なDesignを設定すると、最大3商品までのレコメンドが埋まった状態でのHTMLが返却されます。
凄くシンプルなんですが、この方法だとちょっと問題が起きるときがあります。

#### 起きる問題：値が無いHTMLが返却される場合がある

これは部分デザインを有効にした場合に起きるのですが、仮にレコメンドを要求しても2個しか返ってこないとします。
上で書いたサンプルは3つまでの要素を書いているので、どう返ってくるかと言うと…

```html
<!-- レコメンド結果が2商品しかなかった場合に返却されるHTML例 --> 
<div>
   <ul>
     <!-- 1商品目 -->
     <li>商品名: 素敵な商品A <span class="sku">(ITEM-001)</span></li>
     <li>商品カテゴリ: カテゴリA > カテゴリB </li>
     <li>価格: <span class="price"> 5000 円</span></li>
     <li><img src="/path/to/item_image/item-001_top.jpg" /></li>
   </ul>
   <ul>
     <!-- 2商品目 -->
     <li>商品名: イケてる商品B <span class="sku">(ITEM-021)</span></li>
     <li>商品カテゴリ: カテゴリA > カテゴリC </li>
     <li>価格: <span class="price"> 980 円</span></li>
     <li><img src="/path/to/item_image/item-021_top.jpg" /></li>
   </ul>
   <ul>
     <!-- 3商品目(問題あり！) -->
     <li>商品名:  <span class="sku">()</span></li>
     <li>商品カテゴリ:  >  </li>
     <li>価格: <span class="price">  円</span></li>
     <li><img src="" />
   </ul>
</div>
```

上記のように返却されてきてしまいます。
注目してほしいのは3商品目のHTML部分です。
値がなかったので、その部分だけが空白値で返ってきてしまい、このまま表示するとおかしい表示になってしまいます。

そこでパターン2の実装方法がおすすめとなります。

### その2. 内蔵のテンプレートエンジンを利用する

Adobe TargetのレコメンデーションDesignではテンプレートエンジン(デザイン言語)のVelocityを採用しています。
このVelocityを使うことでもっと簡潔に、カスタマイズしやすいDesignを作ることが可能です。

[Velocity を使用したデザインのカスタマイズ | Adobe Target](https://experienceleague.adobe.com/docs/target/using/recommendations/recommendations-design/customizing-a-template.html?lang=ja#recommendations)

早速さっきのHTMLをVelocityを使った場合で書き直してみましょう。

```html
<!-- Velocity 記法を使って先程のデザインHTMLを書き換えた場合 -->
<div>
#set( $loopCount = 3)
#foreach($e in $entities)
 #if($velocityCount > $loopCount)
   #break
 #end
 #if($e.id != "")
   <ul>
     <!-- {$velocityCount}商品目 -->
     <li>商品名: ${e.name} <span class="sku">(${e.id})</span></li>
     <li>商品カテゴリ: ${e.maincategory} > ${e.subcategory} </li>
     <li>価格: <span class="price"> ${e.price} 円</span></li>
     <li><img class="item_image" src="${e.thumbnailUrl}" /></li>
   </ul>
 #end
#end
</div>
```

- $entities → レコメンドされた商品データ配列
- $velocityCount → foreachなどのループ中にループ回数を記録している自動定義変数

velocity記法を使うことで、配列操作やif文などが使えるようになります。
今回はレコメンド情報配列の中に商品ID(entity.id)の有無を判断してHTMLを出す、出さないを制御しています。
(これはIDと例えば商品名(entity.name)の有無も判断に入れてもいいと思います)

また、単純にループ処理をした場合、3商品以上がレコメンド候補として入ってきた場合に全部出てきてしまうので、最初に上限を決めてループ回数を固定化するif文での判定も入れています。


## 参考資料
- [Velocity を使用したデザインのカスタマイズ | Adobe Target](https://experienceleague.adobe.com/docs/target/using/recommendations/recommendations-design/customizing-a-template.html?lang=ja)
- [Apache Velocity User guide](https://velocity.apache.org/engine/1.7/user-guide.html)