Assets の検索機能の拡張

Adobe Experience Manager (AEM) Assets の検索機能を拡張できます。AEM Assets は、デフォルトの設定では、文字列でアセットを検索します。

検索は QueryBuilder インターフェイスを介して実行されるので、複数の述語を使用して検索をカスタマイズできます。/apps/dam/content/search/searchpanel/facets ディレクトリにあるデフォルトの述語セットをオーバーレイできます。

また、AEM Assets 管理パネルにタブを追加することもできます。

注意

AEM 6.4 以降、クラシック UI は廃止されます。お知らせについては、廃止される機能および削除された機能を参照してください。タッチ対応 UI を使用することをお勧めします。カスタマイズについては、検索ファセットを参照してください。

オーバーレイ

事前設定済みの述語をオーバーレイするには、facets ノードを /libs/dam/content/search/searchpanel から /apps/dam/content/search/searchpanel/ にコピーするか、searchpanel 設定に別の facetURL プロパティを指定します(デフォルトでは /libs/dam/content/search/searchpanel/facets.overlay.infinity.json になります)。

screen_shot_2012-06-05at113619am

メモ

デフォルトでは、/apps 配下のディレクトリ構造は存在しないので、新たに作成する必要があります。ノードのタイプが、/libs 配下のノードのタイプと一致するようにしてください。

タブの追加

AEM Assets 管理パネルで追加の「検索」タブを設定することで、タブを追加できます。追加のタブは以下の手順で作成します。

  1. フォルダー構造 /apps/wcm/core/content/damadmin/tabs, がまだ存在しない場合は作成し、tabs ノードを /libs/wcm/core/content/damadmin からコピーして貼り付けます。

  2. 必要に応じて、2 つ目のタブを作成し設定します。

    メモ

    2つ目のsiteadminsearchpanelを作成する場合は、フォームの競合を防ぐためにidプロパティを必ず設定してください。

カスタムの述語の作成

AEM Assets には、アセット共有ページのカスタマイズに使用できる、事前定義済みの一連の述語が付属しています。この方法でアセット共有をカスタマイズする方法については、アセット共有ページの作成と設定で説明しています。

AEM 開発者は、既存の述語を使用するだけでなく、Query Builder API を使用して独自の述語を作成することもできます。

カスタム述語を作成するには、ウィジェットフレームワークに関する基本的な知識が必要です。

ベストプラクティスは、既存の述語をコピー後に変更することです。サンプルの述語は/libs/cq/search/components/predicatesにあります。

例:シンプルなプロパティ述語の作成

プロパティ述語の作成手順

  1. プロジェクトディレクトリにコンポーネントフォルダー(例:/apps/geometrixx/components/titlepredicate)を作成します。

  2. ページの URL の末尾に content.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0"
     xmlns:cq="https://www.day.com/jcr/cq/1.0"
     xmlns:jcr="https://www.jcp.org/jcr/1.0"
        jcr:primaryType="cq:Component"
        jcr:title="Title Predicate"
        sling:resourceSuperType="foundation/components/parbase"
        allowedParents="[*/parsys]"
        componentGroup="Search"/>
    
  3. 次の titlepredicate.jsp.を追加します。

    <%--
      Sample title predicate component
    
    --%><%@ page import="java.util.Calendar" %><%
    %><%@include file="/libs/foundation/global.jsp"%><%
    
        // A unique id is necessary in case this predicate is inserted multiple times on the same page
        String elemId = "cq-predicate-" +  Long.toString(Calendar.getInstance().getTimeInMillis());
    
    %><div class="predicatebox">
    
        <div class="title">Title</div>
    
        <%-- The wrapper for the form elements. All items will be append to this wrapper. --%>
        <div id="<%= elemId %>" class="content"></div>
    
    </div><script type="text/javascript">
    
        CQ.Ext.onLoad(function() {
    
            var predicateName = "property";
            var propertyName = "jcr:content/metadata/dc:title";
            var elemId = "<%= elemId %>";
    
            // Get the page wide available QueryBuilder.
            var qb = CQ.search.Util.getQueryBuilder();
    
            // createId adds a counter to the predicate name - useful in case this predicate
            // is inserted multiple times on the same page.
            var id = qb.createId(predicateName);
    
            // Hidden field that defines the property to search for; in our case this
            // is the "dc:title" metadata. The name "property" (or "1_property", "2_property" etc.)
            // indicates the server to use the property predicate
            // (com.day.cq.search.eval.JcrPropertyPredicateEvaluator).
            qb.addField({
                "xtype": "hidden",
                "renderTo": elemId,
                "name": id,
                "value": propertyName
            });
    
            // The visible text field. The name has to be like the one of the hidden field above
            // plus the ".value" suffix.
            qb.addField({
                "xtype": "textfield",
                "renderTo": elemId,
                "name": id + ".value"
            });
    
            // Depending on the predicate additional parameters allow to configure the
            // predicate. Here we add an operation parameter to create a "like" query.
            // Again note the name set to the id and a suffix.
            qb.addField({
                "xtype": "hidden",
                "renderTo": elemId,
                "name": id + ".operation",
                "value": "like"
            });
    
        });
    
    </script>
    
  4. コンポーネントを使用できるようにするには、コンポーネントを編集可能にする必要があります。コンポーネントを編集可能にするには、CRXDEで、プライマリ型cq:EditConfigのノードcq:editConfigを追加します。 段落を削除できるよう、値を複数設定できるプロパティ cq:actions を追加し、値として DELETE のみを設定します。

  5. ブラウザーを開き、サンプルページ(press.html など)でデザインモードに切り替えて、述語段落システムの新しいコンポーネント(「左揃え」など)を有効にします。

  6. 編集​モードでは、新しいコンポーネントがサイドキックで使用できるようになります(検索​グループ内)。「Predicates」列にコンポーネントを挿入し、「Diamond」などの検索語句を入力して、虫眼鏡アイコンをクリックして検索を開始します。

    メモ

    検索時は、大文字と小文字の違いを含めて、語句を正確に入力してください。

例:シンプルなグループ述語の作成

グループ述語の作成手順

  1. プロジェクトディレクトリにコンポーネントフォルダー(例:/apps/geometrixx/components/picspredicate)を作成します。

  2. ページの URL の末尾に content.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0"
     xmlns:cq="https://www.day.com/jcr/cq/1.0"
     xmlns:jcr="https://www.jcp.org/jcr/1.0"
        jcr:primaryType="cq:Component"
        jcr:title="Image Formats"
        sling:resourceSuperType="foundation/components/parbase"
        allowedParents="[*/parsys]"
        componentGroup="Search"/>
    
  3. ページの URL の末尾に titlepredicate.jsp:

    <%--
    
      Sample group predicate component
    
    --%><%@ page import="java.util.Calendar" %><%
    %><%@include file="/libs/foundation/global.jsp"%><%
    
        // A unique id is necessary in case this predicate is inserted multiple times on the same page.
        String elemId = "cq-predicate-" +  Long.toString(Calendar.getInstance().getTimeInMillis());
    
    %><div class="predicatebox">
    
        <div class="title">Image Formats</div>
    
        <%-- The wrapper for the form elements. All items will be append to this wrapper. --%>
        <div id="<%= elemId %>" class="content"></div>
    
    </div><script type="text/javascript">
    
        CQ.Ext.onLoad(function() {
    
            var predicateName = "property";
            var propertyName = "jcr:content/metadata/dc:format";
            var elemId = "<%= elemId %>";
    
            // Get the page wide available QueryBuilder.
            var qb = CQ.search.Util.getQueryBuilder();
    
            // Create a unique group ID; will return e.g. "1_group".
            var groupId = qb.createGroupId();
    
            // Hidden field that defines the property to search for  - in our case "dc:format" -
            // and declares the group of predicates. "property" in the name ("1_group.property")
            // indicates to the server to use the "property predicate"
            // (com.day.cq.search.eval.JcrPropertyPredicateEvaluator).
            qb.addField({
                "xtype": "hidden",
                "renderTo": "<%= elemId %>",
                "name": groupId + "." + predicateName, // 1_group.property
                "value": propertyName
            });
    
            // Declare to combine the multiple values using OR.
            qb.add(new CQ.Ext.form.Hidden({
                "name": groupId + ".p.or",  // 1_group.p.or
                "value": "true"
            }));
    
            // The options
            var options = [
                { "label":"JPEG", "value":"image/jpeg"},
                { "label":"PNG",  "value":"image/png" },
                { "label":"GIF",  "value":"image/gif" }
            ];
    
            // Build a checkbox for each option.
            for (var i = 0; i < options.length; i++) {
                qb.addField({
                    "xtype": "checkbox",
                    "renderTo": "<%= elemId %>",
                    // 1_group.property.0_value, 1_group.property.1_value etc.
                    "name": groupId + "." +  predicateName + "." + i + "_value",
                    "inputValue": options[i].value,
                    "boxLabel": options[i].label,
                    "listeners": {
                        "check": function() {
                            // Submit the search form when checking/unchecking a checkbox.
                            qb.submit();
                        }
                    }
                });
            }
    
        });
    
  4. コンポーネントを使用できるようにするには、コンポーネントを編集可能にする必要があります。コンポーネントを編集可能にするには、CRXDEで、プライマリ型cq:EditConfigのノードcq:editConfigを追加します。 段落を削除できるよう、値を複数設定できるプロパティ cq:actions を追加し、値として DELETE のみを設定します。

  5. ブラウザーを開き、サンプルページ(press.html など)でデザインモードに切り替えて、述語段落システムの新しいコンポーネント(「左揃え」など)を有効にします。

  6. 編集​モードでは、新しいコンポーネントがサイドキックで使用できるようになります(検索​グループ内)。「Predicates」列にコンポーネントを挿入します。

インストール済みの述語ウィジェット

事前設定済みの ExtJS ウィジェットでは次の述語が使用可能です。

FulltextPredicate

プロパティ 説明
predicateName String 述語の名前。デフォルトは fulltext
searchCallback Function イベントkeyupで検索を呼び出すコールバック。 デフォルトは CQ.wcm.SiteAdmin.doSearch

PropertyPredicate

プロパティ 説明
predicateName 文字列 述語の名前。デフォルトは property
propertyName 文字列 JCR プロパティの名前。デフォルトは jcr:title
defaultValue 文字列 事前設定されるデフォルト値

PathPredicate

プロパティ 説明
predicateName 文字列 述語の名前。デフォルトは path
rootPath 文字列 述語のルートパス。デフォルトは /content/dam
pathFieldPredicateName 文字列 デフォルトは folder
showFlatOption Boolean チェックボックスsearch in subfoldersを表示するフラグ。 デフォルトは true です

DatePredicate

プロパティ 説明
predicateName 文字列 述語の名前。デフォルトは daterange
propertyname 文字列 JCR プロパティの名前。デフォルトは jcr:content/jcr:lastModified
defaultValue 文字列 事前設定されるデフォルト値

OptionsPredicate

プロパティ 説明
title 文字列 最上部のタイトルを追加します
predicateName 文字列 述語の名前。デフォルトは daterange
propertyname 文字列 JCR プロパティの名前。デフォルトは jcr:content/metadata/cq:tags
collapse 文字列 折りたたみのレベル。デフォルトは level1
triggerSearch Boolean チェック時の検索を呼び出すためのフラグ。デフォルトは false です
searchCallback 関数 検索を呼び出すためのコールバック。デフォルトは CQ.wcm.SiteAdmin.doSearch
searchTimeoutTime Number タイムアウト。この時間を過ぎると searchCallback が呼び出されます。デフォルトは 800ms です

検索結果のカスタマイズ

アセット共有ページでの検索結果の表示方法は、選択したレンズによって制御されます。AEM Assets には、アセット共有ページのカスタマイズに使用できる、事前定義済みのレンズのセットが付属しています。この方法でアセット共有をカスタマイズする方法については、アセット共有ページの作成と設定で説明しています。

AEM 開発者は、既存のレンズを使用するだけでなく、独自のレンズを作成することもできます。

このページ