AEM タグ付けフレームワーク

コンテンツにタグ付けし、AEM タグ付けインフラストラクチャを利用するには:

  • タグは、cq:Tag タイプのノードとして、分類のルートノードの下に存在する必要があります。

  • タグ付けされたコンテンツノードのノードタイプには、cq:Taggable mixin が含まれている必要があります。

  • TagIDは、コンテンツノードのcq:tagsプロパティに追加され、cq:Tag型のノードに解決されます

タグ:cq:Tag ノードタイプ

タグの宣言は、リポジトリーにおける cq:Tag. タイプのノードにキャプチャされます。

タグは、単純な単語(sky など)にしたり、階層分類(包括的な fruit と具体的な apple の両方を意味する fruit/apple など)を表したりすることができます。

タグは一意のタグ ID によって識別されます。

タグには、タイトル、ローカライズされたタイトル、説明など、任意のメタ情報があります。タイトルは、TagIDが存在する場合は、TagIDではなくユーザーインターフェイスに表示されます。

タグ付けフレームワークでは、作成者やサイト訪問者に、特定の事前定義されたタグだけを使用するよう制限を設けることもできます。

タグの特徴

  • ノードタイプはcq:Tag

  • ノード名はTagID

  • TagIDには常に名前空間が含まれます

  • オプションのjcr:titleプロパティ(UIに表示するタイトル)

  • オプションのjcr:descriptionプロパティ

  • 子ノードが含まれている場合、コンテナタグと呼ばれます。

  • 分類のルートノードと呼ばれる基本パスの下のリポジトリに保存されます。

タグ ID

タグ ID は、リポジトリ内のタグノードに解決されるパスを識別します。

通常、TagIDは、名前空間で始まる略称TagIDです。または、分類ルートノードから始まる絶対TagIDにすることもできます。

コンテンツにタグ付けするときに、コンテンツがまだ存在しない場合は、cq:tags プロパティがコンテンツノードに追加され、タグ ID がこのプロパティの String 配列値に追加されます。

タグ ID は、名前空間とそれに続くローカルタグ ID で構成されます。コンテナタグにはサブタグがあり、これは分類における階層順序を表します。サブタグは、ローカルのTagIDと同じタグを参照するために使用できます。 例えば、コンテンツがサブタグを含むコンテナタグ(「fruit/apple」や「fruit/banana」など)であっても、コンテンツに「fruit」とタグ付けすることができます。

分類のルートノード

分類のルートノードは、リポジトリー内にあるすべてのタグの基本パスです。分類のルートノードは、 cq :Tag タイプのノードにすることが​できません

AEM の基本パスは /content/ cq :tags であり、ルートノードのタイプは cq :Folder です。

タグの名前空間

名前空間を使用するとグループ化をおこなうことができます。最も一般的な使用例は、(Web)サイトごと(公開、内部、ポータルなど)に名前空間を持つ場合、または大規模なアプリケーションごと(WCM、アセット、コミュニティなど)に名前空間を持つ場合ですが、他の様々なニーズに対しても使用できます。 名前空間は、現在のコンテンツに適用されるタグのサブセット(特定の名前空間のタグなど)のみを表示するためにユーザーインターフェイスで使用されます。

タグの名前空間は、分類サブツリーの最初のレベルです。これは、分類のルートノードの直下のノードです。の直下のノードです。名前空間は cq:Tag タイプのノードで、その親は cq:Tag ノードタイプではありません。

すべてのタグには名前空間があります。名前空間を指定しない場合、タグはデフォルトの名前空間(TagID default)に割り当てられます(TitleはStandard Tags),/content/cq:tags/default.

コンテナタグ

コンテナタグは、任意の数およびタイプの子ノードを含む、cq:Tag タイプのノードです。これにより、カスタムメタデータを使用してタグモデルを強化できます。

さらに、コンテナタグ(またはスーパータグ)は分類において、すべてのサブタグの小計としての機能を果たします。例えば fruit/apple でタグ付けされたコンテンツは、fruit でタグ付けされたとも見なされます。つまり、fruit でタグ付けされたコンテンツを検索すると、fruit/apple でタグ付けされたコンテンツも検索されます。

タグ ID の解決

タグ ID にコロン「:」が含まれている場合、そのコロンによってタグやサブ分類から名前空間が区別され、その後、タグやサブ分類は通常のスラッシュ「/」で区別されます。タグ ID にコロンが含まれていない場合は、デフォルトの名前空間が暗示されます。

タグの標準的で唯一の場所は/content/cq:tagsの下です。

cq:Tagノードを指していない、既存でないパスまたはパスを参照するタグは、無効と見なされ、無視されます。

次の表に、タグ ID の例とその要素、リポジトリでそのタグ ID がどのように絶対パスに解決されるかを示します。

次の表に、タグ ID の例とその要素、リポジトリでそのタグ ID がどのように絶対パスに解決されるかを示します。
次の表に、タグ ID の例とその要素、リポジトリでそのタグ ID がどのように絶対パスに解決されるかを示します。

タグ ID
名前空間 ローカル ID コンテナタグ リーフタグ Repository
絶対タグパス
dam:fruit/apple/braeburn dam fruit/apple/braeburn 果物、リンゴ ブレーバーン /content:tags/dam/fruit/apple/braeburn
color/red default color/red カラー red /content/cq:tags/default/color/red
sky default sky (なし) sky /content/cq:tags/default/sky
dam: ダム (なし) (なし) (なし、名前空間) /content/cq:tags/dam
/content/cq:tags/カテゴリ/car カテゴリ /content/cq:tags/カテゴリ/car

タグタイトルのローカリゼーション

タグにオプションのタイトル文字列(jcr:title)が含まれる場合は、jcr:title.<locale>プロパティを追加して、表示するタイトルをローカライズできます。

詳しくは、以下を参照してください。

アクセス制御

タグは、リポジトリ内で分類のルートノードの下にノードとして存在します。特定の名前空間で作成者やサイト訪問者がタグを作成することを許可または拒否するには、リポジトリで適切なACLを設定します。

また、特定のタグまたは名前空間に対する読み取り権限を拒否することで、特定のコンテンツへのタグの適用を制御できます。

一般的な方法には次のものがあります。

  • すべての名前空間への書き込みアクセス(/content/cq:tags 下への add/modify)をtag-administrators グループ/役割に許可する。このグループは、追加設定なしで使用できる AEM に付属しています。

  • 読み取り可能にする必要があるすべての名前空間への読み取りアクセスをユーザー/作成者に許可する。

  • タグを自由に定義できる名前空間(/content/cq:tags/some_namespaceの下のadd_node)への書き込みアクセスを許可する

タグ付け可能なコンテンツ:cq:Taggable Mixin

アプリケーション開発者がコンテンツタイプにタグ付けを付加するには、ノードの登録(CND)に cq:Taggable Mixin または cq:OwnerTaggable Mixin を含める必要があります。

cq:OwnerTaggable Mixin は cq:Taggable から継承されており、その目的は、所有者または作成者がコンテンツを分類できることを示すことです。AEM では、cq:PageContent ノードの属性にすぎません。cq:OwnerTaggable Mixin は、タグ付けフレームワークには必要ありません。

メモ

集約されたコンテンツアイテムの最上位ノード(またはその jcr:content ノード)では、タグの有効化だけをおこなうことをお勧めします。以下に例を示します。

  • jcr:contentノードのタイプがcq:PageContentで、cq:Taggableミックスインが含まれているページ(cq:Page)。

  • アセット(cq:Asset)。jcr:content/metadataノードには常にcq:Taggableミックスインがあります。

ノードタイプの表記(CND)

ノードタイプの定義は、リポジトリー内に CND ファイルとして存在します。CND表記は、JCRドキュメントここの一部として定義されています。

AEM に含まれるノードタイプの基本的な定義は、次のようになります。

[cq:Tag] > mix:title, nt:base
    orderable
    - * (undefined) multiple
    - * (undefined)
    + * (nt:base) = cq:Tag version

[cq:Taggable]
    mixin
    - cq:tags (string) multiple

[cq:OwnerTaggable] > cq:Taggable
    mixin

タグ付けされたコンテンツ:cq:tags プロパティ

cq:tags プロパティは、作成者またはサイト訪問者によってコンテンツに 1 つ以上のタグ ID が割り当てられたときにその ID を格納するための文字列配列です。このプロパティは、cq:Taggable Mixin で定義されているノードに追加した場合にのみ意味があります。

メモ

AEM のタグ付け機能を使用するには、カスタムで開発されたアプリケーションで cq:tags 以外のタグプロパティを定義しないでください。

タグの移動と統合

次に、タグ付けコンソールを使用してタグの移動または統合を実行した場合のリポジトリ内での影響について説明します。

  • タグAを/content/cq:tagsの下のタグBに移動または結合する場合:

    • タグAは削除されず、cq:movedToプロパティを取得します。
    • タグBが作成され(移動の場合)、cq:backlinksプロパティが取得されます。
  • cq:movedTo はタグ B を指します。

    このプロパティは、タグ A がタグ B に移動または結合されたことを意味します。タグ B を移動すると、それに応じてこのプロパティが更新されます。タグ A は非表示になり、タグ A を示すコンテンツノード内のタグ ID を解決するリポジトリに保持されるだけになります。タグガベージコレクターは、タグ A のように、コンテンツノードで指定されなくなったタグを削除します。

    cq:movedToプロパティの特別な値はnirvanaです。タグが削除された場合に適用されますが、リポジトリから削除することはできません。これは、保持する必要があるcq:movedToを持つサブタグが存在するためです。

    メモ

    cq:movedTo プロパティは、次のいずれかの条件を満たす場合にのみ、移動または結合されたタグに追加されます。

    1. タグがコンテンツで使用されている(参照が含まれている)場合、OR
    2. タグには、既に移動された子が含まれています。
  • cq:backlinks は、他のリスト(タグBとの間で移動または結合されたすべてのタグのを保持する)。これは、タグBの移動/結合/削除時やタグBのアクティブ化時に、 cq:movedToプロパティを最新の状態に維持する必要が大きい場合です。

メモ

cq:backlinks プロパティは、次のいずれかの条件を満たす場合にのみ、移動または結合されたタグに追加されます。

  1. タグがコンテンツで使用されている(参照が含まれている)場合、OR
  2. タグには、既に移動された子が含まれています。
  • コンテンツノードの cq:tags プロパティを読み取ると、以下のように解決されます。

    1. /content/cq:tags 下で一致するものが見つからない場合、タグは返されません。

    2. タグに cq:movedTo プロパティが設定されている場合は、参照先のタグ ID が使用されます。

      これは、その次のタグに cq:movedTo プロパティがある限り繰り返されます。

    3. 次のタグに cq:movedTo プロパティがない場合は、そのタグが読み取られます。

  • タグが移動またはマージされたときにその変更を発行するには、cq:Tag ノードとそのすべてのバックリンクを複製する必要があります。この処理は、タグ管理コンソールでタグがアクティベートされたときに自動的に実行されます。

  • 後でページの cq:tags プロパティに対して更新がおこなわれると、「以前の」参照が自動的にクリーンアップされます。移動したタグを API で解決すると移動先のタグが戻され、移動先のタグ ID が提供されることから、この処理がトリガーされます。

タグの移行

Experience Manager6.4以降のタグは/content/cq:tagsに格納され、/etc/tagsに格納されていました。 ただし、Adobe Experience Managerが以前のバージョンからアップグレードされた場合、タグは古い場所/etc/tagsに残っています。 アップグレードしたシステムのタグは、/content/cq:tagsの下に移行する必要があります。

メモ

タグページのページプロパティでは、タグベースパス(/etc/tags/geometrixx-outdoors/activity/bikingなど)をハードコーディングする代わりに、タグID(例:geometrixx-outdoors:activity/biking)を使用することをお勧めします。

リストタグにはcom.day.cq.tagging.servlets.TagListServletを使用できます。

メモ

タグマネージャーAPIをリソースとして使用することをお勧めします。

アップグレードしたAEMインスタンスがTagManager APIをサポートする場合

  1. コンポーネントの開始時に、TagManager APIはアップグレードされたAEMインスタンスであるかどうかを検出します。 アップグレードしたシステムでは、タグは/etc/tagsの下に保存されます。

  2. 次に、TagManager APIは下位互換モードで実行されます。つまり、APIは/etc/tagsをベースパスとして使用します。 そうでない場合は、新しい場所/content/cq:tagsが使用されます。

  3. タグの場所を更新します。

  4. タグを新しい場所に移行した後、次のスクリプトを実行します。

import org.apache.sling.api.resource.*
import javax.jcr.*

ResourceResolverFactory resourceResolverFactory = osgi.getService(ResourceResolverFactory.class);
ResourceResolver resolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
Session session = resolver.adaptTo(Session.class);

def queryManager = session.workspace.queryManager;
def statement = "/jcr:root/content/cq:tags//element(*, cq:Tag)[jcr:contains(@cq:movedTo,\'/etc/tags\') or jcr:contains(@cq:backlinks,\'/etc/tags\')]";
def query = queryManager.createQuery(statement, "xpath");

println "query = ${query.statement}\n";

def tags = query.execute().getNodes();


tags.each { node ->
        def tagPath = node.path;
        println "tag = ${tagPath}";

        if(node.hasProperty("cq:movedTo") && node.getProperty("cq:movedTo").getValue().toString().startsWith("/etc/tags")){

                def movedTo = node.getProperty("cq:movedTo").getValue().toString();

                println "cq:movedTo = ${movedTo} \n";

                movedTo = movedTo.replace("/etc/tags","/content/cq:tags");
                node.setProperty("cq:movedTo",movedTo);
        } else if(node.hasProperty("cq:backlinks")){

               String[] backLinks = node.getProperty("cq:backlinks").getValues();
               int count = 0;

               backLinks.each { value ->
                       if(value.startsWith("/etc/tags")){
                               println "cq:backlinks = ${value}\n";
                               backLinks[count] = value.replace("/etc/tags","/content/cq:tags");
    }
                       count++;
               }

               node.setProperty("cq:backlinks",backLinks);
  }
}
session.save();

println "---------------------------------Success-------------------------------------"

スクリプトは、cq:movedTo/cq:backLinksプロパティの値に/etc/tagsが含まれるすべてのタグを取得します。 次に、取得した結果セットを繰り返し処理し、cq:movedTocq:backlinksのプロパティ値を/content/cq:tagsパスに解決します(値に/etc/tagsが検出された場合)。

アップグレードしたAEMインスタンスがClasic UIで実行される場合

メモ

クラシックUIは、ダウンタイムゼロの互換性がなく、新しいタグ基本パスをサポートしていません。 /etc/tagsよりも古いUIを使用する場合は、cq-taggingコンポーネントを再起動して作成する必要があります。

アップグレードしたAEMインスタンスがTagManager APIでサポートされ、クラシックUIで実行される場合:

  1. 古いタグベースパス/etc/tagsへの参照をtagIdまたは新しいタグの場所/content/cq:tagsを使用して置き換えると、CRXの新しい場所/content/cq:tagsにタグを移行し、その後でコンポーネントを再起動できます。

  2. タグを新しい場所に移行した後、上記のスクリプトを実行します。

このページ

Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now