ヘッダーをスキップ
Oracle® Fusion Middleware WebCenter Sites開発者ガイド
11gリリース1 (11.1.1.8.0)
E49681-03
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

48 プロキシ・アセット: サード・パーティ・コンテンツ・ソースの統合

この章では、プロキシ・アセット・タイプ・フレームワークを使用して、WebCenter Sitesで配信したサイトに外部Webコンテンツを統合する方法について説明します。

この章には次の項が含まれます。

48.1 概要

原則

プロキシ・アセットとは、リモートの場所に保管され、その場所で管理されているコンテンツを表します。これについては、図48-1を参照してください。

図48-1 プロキシ・アセットのアーキテクチャ

図48-1の説明が続きます
「図48-1 プロキシ・アセットのアーキテクチャ」の説明

このアーキテクチャの内容は、次のとおりです。


注意:

プロキシ・アセットは、使用されるもののみがSitesデータベースに永久的に格納されます。たとえば、検索結果のレンダリング中に作成されるプロキシ・アセットは、その後、専用のクリーニング・イベントで消去されます。


Contributorインタフェース

WebCenter Sitesデータベースに新しいプロキシ・アセット・タイプを登録した後で、開発者は、適切なUIカスタマイズを提供して、コントリビュータが外部コンテンツとの対話を始められるようにする必要があります。

実装するUIカスタマイズの特性は、コントリビュータに固有の要件に応じて異なります。たとえば、Contributorインタフェースの検索機能は、多くの場合、外部リポジトリに固有の検索サービスにフックされることになります。

これが行われていて、外部コンテンツがプロキシ・アセットの形式でContributorインタフェースに表示されていると、それらのアセットは標準アセットとほとんど同じように機能します。つまり、コントリビュータは、次の操作を実行できるようになります。

デフォルトの調査画面は、すべてのプロキシ・タイプに使用できます。


注意:

次の制限が適用されます。

  • 外部コンテンツのライフサイクルは、サード・パーティのUIで全体的に管理することを想定しています。つまり、WebCenter Sitesには、外部リポジトリへの読取りアクセスのみが必要になります。そのため、編集やバージョニングなどのUIアクションは、すべてのプロキシ・アセットタイプに対してデフォルトで無効化されています。

  • プロキシ・アセットには、関連アセットまたはサブタイプを含めることができません。

  • 外部コンテンツ・リポジトリは、コントリビューションと配信の両方のWebCenter Sitesインスタンスからアクセスできるようにする必要があります。


48.2 ユーザー・インタフェースのカスタマイズ

WebCenter Sitesの使用感を向上するために、ユーザー・インタフェースは様々な方法でカスタマイズできます。この項では、サード・パーティ・ソフトウェアと同期するように、UI部分をカスタマイズする方法の詳細について説明します。

この項の内容は、次のとおりです。

48.2.1 検索スタート・メニューのカスタマイズ

WebCenter SitesのUIでは、ユーザーは、図48-2に示す検索スタート・メニューを選択して、特定のアセット・タイプに限定した検索を実行します。

図48-2 「検索タイプ」スタート・メニューの選択

図48-2の説明が続きます
「図48-2 「検索タイプ」スタート・メニューの選択」の説明

特定のアセット・タイプに応じて検索をカスタマイズするには、次のエレメントを作成して、コントローラ・エレメントUI/Data/Search/Searchをオーバーライドします。

CustomElements/<AssetType>/UI/Data/Search/SearchAction
CustomElements/<AssetType>/UI/Data/Search/SearchJson

コントローラ・エレメントと、エレメントのオーバーライドの詳細は、第III部「Contributorインタフェースのカスタマイズ」を参照してください。

UI/Data/Search/Searchは、検索コードを実行し、グリッド・ウィジェット(ドッキングまたはドッキング解除された、リスト表示またはサムネイル表示)での利用に適したJSONデータを生成します。

このJSONデータは、有効なdojoデータストアにする必要があります。第48.3.4項「検索のカスタマイズ」第48.2.2項「コンテンツ・ツリーのカスタマイズ」に、実際の実装例を示しています。

48.2.2 コンテンツ・ツリーのカスタマイズ

コンテンツ・ツリーは、新規または既存のツリー・タブに含めるカスタムのツリー・セクションを定義することでカスタマイズできます。カスタム・ツリー・タブのセクションの詳細は、『WebCenter Sites管理者ガイド』を参照してください。

カスタム・ツリー・タブのセクションは、なんらかのレンダリング・ロジック(最終的にはツリー・ウィジェットで使用される)に基づいてデータを生成するJSPエレメントを参照します。ツリー・データは、次のユーティリティ・エレメントを使用して生成されます。

  • OpenMarket/Gator/UIFramework/BuildTreeNodeId: ツリー・ノードIDを生成します

  • OpenMarket/Gator/UIFramework/BuildTreeNode: 適切に書式設定されたツリー・ノード・データを生成します

次の例では、ツリー・ノードがアセットを表しているかどうかに応じたツリー・ノードの作成方法を示しています(アセット・ノードと非定型ノードの比較)。詳細は、第34章「WebCenter SitesのAdminインタフェースのカスタマイズ」を参照してください。

例1: アセットを表すツリー・ノードの作成

この例は、単一のアセット・ノードを表すツリー・ノードを生成する方法を示しています。このノードは、ダブルクリックされたときにinspectアクションを実行します(executeFunctionパラメータを参照)。つまり、アセットのデフォルト調査ビューが新しいタブにレンダリングされるようになります(そのアセットが、すでにタブ内で開かれている場合は、フォーカスが移動します)。

<%--
- Generates a tree node id.
- The element expects the asset id and type to be passed in parameters
- called respectively "ID" and "AssetType".
- The generated id is stored in a Sites variable called "TreeNodeID"
--%>
<ics:callelement element="OpenMarket/Gator/UIFramework/BuildTreeNodeID">
     <ics:argument name="AssetType" value="Article" />
     <ics:argument name="ID" value="1234567890" />
</ics:callelement>

<%-- 
- Generates a tree node for this asset.
- Note that this element implicitly consumes variables
- currently present in the ICS scope, including "TreeNodeID"
--%>
<ics:callelement element="OpenMarket/Gator/UIFramework/BuildTreeNode">
     <ics:argument name="Label" value="Node Label, for example asset name or other
                   readable string" />
     <ics:argument name="Description" value="Some optional tooltip text" />
     <ics:argument name="executeFunction" value="inspect" />
</ics:callelement>

例2: 非定型ツリー・ノードの作成

ツリー・ノードには、アセットを表さないものがあります。そのようなノードを、非定型ノードと呼びます。次の例は、親ノードを表す非定型ノードの生成方法を示しています。親ノードとは、子を持つノードで、開いたり閉じたりできます。

<%--
- Generates a tree node id. 
- For adhoc nodes, the expected parameter is called "AdHoc",
- and can be any arbitrary string, which must be unique across tree nodes
--%>
<ics:callelement element="OpenMarket/Gator/UIFramework/BuildTreeNodeID" >
  <ics:argument name="AdHoc" value="SomeUniqueString" />
</ics:callelement>

<%-- 
- Generates a "LoadURL", that is the URL to be called when a tree node
- is expanded. In this case, we're calling the default utility SiteCatalog entry
- (OpenMarket/Gator/UIFramework/LoadTab) which, in turn, will invoke
- a custom element ("Some/Other/Element" in our example), in charge
- of generating the child nodes, based on some custom logic.
--%>
<satellite:link
       assembler="query" 
       pagename="OpenMarket/Gator/UIFramework/LoadTab"
       outstring="LoadURL">
  <satellite:argument name="populate" value="Some/Other/Element"/>
  <satellite:argument name="op" value="load"/>
</satellite:link>

<%--
- Generates the corresponding tree node data
- Note that this element consumes the "LoadURL" variable previously generated.
- The presence of LoadURL indicates whether a node should be marked as expandable
or not.
--%>
<ics:callelement element="OpenMarket/Gator/UIFramework/BuildTreeNode">
  <ics:argument name="Label" value="Some meaningful node label" />
</ics:callelement>

48.3 WebCenter Sites Contributorインタフェースへの外部コンテンツの統合

コントリビュータが外部コンテンツを使用して作業できるようにするには、開発者が、それに必要なUI統合コードを実装しておく必要があります。

この項では、事例を示すためにダミーのコンテンツ・リポジトリを使用して、次の項目を統合するための手順について説明します。

この項の内容は、次のとおりです。

48.3.1 事例: ダミー・リポジトリ

サンプル・データの設定

WebCenter Sites Webアプリケーションに直接デプロイされている静的なJSONファイルのセットを使用して、ダミーのコンテンツ・リポジトリをエミュレートします。ダミーのコンテンツは、メディア・コンテンツ(イメージ)であると想定します。

これらのJSONファイルでは、次のサービスをシミュレートします。

  • 特定の用語に対するリポジトリの検索(すべて、"ski"または"surfing"について検索すると、実際の結果が返されます): http://localhost:7001/sites/samples/search/<searchterm>.json

  • すべてのコンテンツ・カテゴリの取得("Ski"および"Surfing"): http://localhost:7001/sites/samples/browse/categories.json

  • 特定のカテゴリに対するすべてのダミー・コンテンツの取得: http://localhost:7001/sites/samples/browse/<category>.json

  • 特定のコンテンツIDに対するメタデータの取得: http://localhost:7001/sites/samples/content/<id>.json

たとえば、/samples/search/ski.jsonは、次のサンプル・コンテンツを返します。

{
  "items": [
    {
      "id": "1001", 
      "title": "Yellow Skier",
      "foo": "bar1",
      "lastModified": "1354735336444",
      "thumbnail": "samples/images/image7_thumbnail.png"
    },
    {
      "id": "1002", 
      "title": "Female Skier",
      "foo": "bar2",
      "lastModified": "1354735336444",
      "thumbnail": "samples/images/image8_thumbnail.png"
    },
    {
      "id": "1003",
      "title": "Ski Jump",
      "foo": "bar3",
      "lastModified": "1354735336444",
      "thumbnail": "samples/images/image9_thumbnail.png"
    }
  ]
}

このタイプのJSONデータを利用するJSPエレメントの例については、このガイドで後述します。


注意:

サンプル・コードは、/misc/Samples/フォルダ内に格納されています。このフォルダは、WebCenter Sitesに配置されています。プロキシ・アセットに固有のサンプル・コードは、/misc/Samples/SampleProxy/proxy_sample.zip内にあります。


ダミー・リポジトリからのデータの取得

コードの重複を避けるために、外部コンテンツ・ソースの問合せに必要なロジックは、Dummy/GetDataという専用エレメントにカプセル化します。この例では、データはJSON形式で返されます。そのため、この例では、jersey (http://jersey.java.net/)とjettison (http://jettison.codehaus.org/)ライブラリを使用します。これらのライブラリは、受信JSONデータを取得してデシリアライズするために、WebCenter SitesのWebアプリケーションにデプロイされています。

このエレメントは、serviceURLというICS変数で問合せ(たとえば、/search/ski.json)を受け取り、ics.SetObj(String, Object)を使用してICSスコープ内に格納されたJSONArrayオブジェクトを返します。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ page import="com.sun.jersey.api.client.*" %>
<%@ page import="com.sun.jersey.api.client.config.*" %>
<%@ page import="org.codehaus.jettison.json.*"%>
<cs:ftcs>
<%
//
// Gets data from dummy repository
// This element expects an ICS variable "serviceURL"
// 
Client client = Client.create();
//
// Host, port and webapp prefix are hardcoded for simplicity, modify as
// appropriate.
// In a real-world scenario, the base service URL would probably be stored in
// a configuration file.
//
WebResource res = client.resource("http://localhost:7001/sites/samples" + 
                  ics.GetVar("serviceURL"));
ClientResponse resp = res.accept("application/json").get(ClientResponse.class);
JSONArray list;
if (resp.getStatus() != 200) {
         list = new JSONArray(); // empty array
}
else {
       JSONObject json = new JSONObject(resp.getEntity(String.class));
       list = json.getJSONArray("items");
}

// store the object in the ICS scope
ics.SetObj("items", list);
%>
</cs:ftcs>

48.3.2 新しいプロキシ・アセット・タイプの登録

WebCenter Sitesリポジトリで、この例でのダミー・コンテンツを表すには、新しいプロキシ・アセット・タイプを定義する必要があります。

プロキシ・アセット・タイプを作成するには、次の手順を実行します。

  1. 「管理」タブで、「プロキシ・アセット・マネージャ」を開きます。「新規追加」をダブルクリックします。

    「新規プロキシ・アセット・タイプの追加」ページが表示されます。

    図48-3 「新規プロキシ・アセット・タイプの追加」ページ

    図48-3の説明が続きます
    「図48-3 「新規プロキシ・アセット・タイプの追加」ページ」の説明

  2. 「名前」フィールドに、プロキシ・アセット・タイプの名前を入力します。同様に、「説明」フィールドに説明を追加して、「複数形」フィールドに名前の複数形を入力します。


    注意:

    Contributorインタフェースでは、プロキシ・アセットを作成または編集できません。そのため、この手順では、「検索」スタート・メニューのみを有効化する必要があります。


    この例では(さらに、このドキュメントの後続部分で使用するために)、「名前」フィールドにDummy「説明」フィールドにDummy「複数形」フィールドにDummiesと入力します。

  3. 「保存」をクリックします。


注意:

「プロキシ・アセット・メーカー」は、新しいアセット・タイプを登録して、それと同じ名前で単一の表を作成します。プロキシ・アセット表は、標準アセット・メタデータのサブセットのみを保持し、唯一の固有列externalidを定義します。このフィールドは、外部リポジトリに含まれる外部コンテンツの識別子を保管するためのものです。


48.3.3 UI統合コードの実装

アセットは、Contributorインタフェースの様々な場所に表示されます。たとえば、次のような場所が該当します。

  • アセット・フォーム(アセット参照を含むフィールド)

  • 検索結果

  • コンテンツ・ツリー・パネル

それぞれの場合で、実際の統合コードは、要件と利用可能なカスタマイズ・フックに応じて様々に異なります。ただし、どの場合でも、「Contributorインタフェースに表示される外部コンテンツは、すべてプロキシ・アセットとして登録されている必要がある」という原則に従う必要があります。

実際には、外部コンテンツ・ソース内のコンテンツ識別子をexternalidフィールドで参照する、プロキシ・アセットを作成(または再使用)するということです。これは、通常のAsset APIのクラスとメソッドを使用することで実現できます。ただし、これを簡単にするために、プロキシJSPタグ・ライブラリが用意されています。

これには、次に示すユーティリティ・タグが含まれています。このタグは、特定の外部コンテンツをプロキシ・アセット・タイプとして登録するためのものです。

  • <proxy:register />

さらに、データ・グリッド・ウィジェット(検索など)のJSONデータストアを生成するためのユーティリティ・タグも含まれています。これらのタグは、次のとおりです。

  • <proxy:createstore />: 新しいストアを初期化します

  • <proxy:addstoreitem />: アイテムを特定のストアに追加します

  • <proxy:tojson />: ストアをJSONにシリアライズします

詳細は、Oracle Fusion Middleware WebCenter Sitesタグ・リファレンスを参照してください。また、コード例は、第48.3.4項「検索のカスタマイズ」を参照してください。

48.3.4 検索のカスタマイズ

第48.2.1項「検索スタート・メニューのカスタマイズ」で説明したように、Dummyアセット・タイプのコントローラ・エレメントUI/Data/Search/Searchをオーバーライドするために、次のエレメントを作成します。

CustomElements/Dummy/UI/Data/Search/SearchAction
CustomElements/Dummy/UI/Data/Search/SearchJson

図48-4 Dummyアセットを表示する検索ドロップダウン

図48-4の説明が続きます
「図48-4 Dummyアセットを表示する検索ドロップダウン」の説明

図に示すように、検索ドロップダウンにDummyが表示されます。Dummyを選択すると(このプロキシ・アセット・タイプの名前はすでに作成されていることを意味します)、Luceneベースの検索ではなく、カスタムの検索コードが実行されます。

完全なカスタム検索を実装するために、このセクションの残りのトピックを完了してください。

この項の内容は、次のとおりです。

48.3.4.1 提供済のサード・パーティAPIを使用した検索結果の取得

CustomElements/Dummy/UI/Data/Search/SearchActionでは、第48.3.1項「事例: ダミー・リポジトリ」で作成したエレメントを使用して、JSONデータを取得します。

このコード例が、取得に使用されます。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
<%@ taglib prefix="proxy" uri="futuretense_cs/proxy.tld"%>
<%@ page import="org.codehaus.jettison.json.*"%>
<%@ page import="COM.FutureTense.Interfaces.Utilities"%>
<cs:ftcs>

<%
// in this dummy example, only the empty search string, 'ski' or 'surfing' will 
// return results String searchTerm = ics.GetVar("searchText");
if (!Utilities.goodString(searchTerm)) searchTerm = "all";
%>
<ics:setvar name="serviceURL" value='<%="/search/" + searchTerm + ".json" %>' />
<ics:callelement element="Dummy/GetData" />
<%
JSONArray list = (JSONArray)ics.GetObj("items");

//
// ...to be continued in the next section
//
%>

</cs:ftcs>

この時点で、listには、外部コンテンツ・ソースから取得したJSONデータが格納されています。

48.3.4.2 検索結果のプロキシ・アセットへの変換、受信検索結果のフィルタ処理、外部コンテンツの登録、および検索グリッド・ウィジェット用のデータ収集

この手順では、一連の段階を通じてコードを作成します。

最初に、新しいデータ・ストアを作成します。

<proxy:createstore store="<storeName>" />

この<storeName>は、データ・ストアを指定する任意の文字列です。

その次に、受信外部コンテンツ・アセットごとに、現在のアセットをプロキシ・アセットとして登録します。

<proxy:register
       externalid="<external_content_identifier>"
       type="<proxy_asset_type>"
       name="<proxy_asset_name>"
       varname="<variable_name>" />

ここで:

  • <external_content_identifier>は、サード・パーティ・リポジトリに含まれる現在の外部コンテンツ・アイテムの識別子です。この例のダミー・リポジトリの場合、この識別子は受信JSONデータのidフィールドで返されます。

  • <proxy_asset_type>は、プロキシ・アセット・タイプの名前です。この例では、"Dummy"になります。

  • <proxy_asset_name>は、Contributorインタフェース全体で名前として使用される、判読可能な文字列です。この例では、受信JSONデータのtitleフィールドで返されます。

  • <variable_name>は、WebCenter Sitesの変数名です。この変数には、現在の外部コンテンツ・アイテムに対応するプロキシ・アセットのIDが格納されます。

その次に、受信登録済プロキシ・アセットごとに、アセットをデータ・ストアに追加します。

<proxy:addstoreitem 
       store="<storeName>"
       id="<proxy_asset_id>"
       type="<proxy_asset_type>" />

ここで:

  • <storeName>は、<proxy:createstore />で定義したデータ・ストアです。

  • <id>は、プロキシ・アセットの識別子です。

  • <type>は、プロキシ・アセット・タイプです。

次に、Dummyプロキシ・アセットタイプの完全なコードを示します。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
<%@ taglib prefix="proxy" uri="futuretense_cs/proxy.tld"%>
<%@ page import="org.codehaus.jettison.json.*"%>
<%@ page import="COM.FutureTense.Interfaces.Utilities"%>
<cs:ftcs>

<%
// in this dummy example, only the empty search string, 'ski' or 'surfing' will
// return results
String searchTerm = ics.GetVar("searchText");
if (!Utilities.goodString(searchTerm)) searchTerm = "all";
%>
<ics:setvar name="serviceURL" value='<%="/search/" + searchTerm + ".json" %>' />
<ics:callelement element="Dummy/GetData" />
<%
JSONArray list = (JSONArray)ics.GetObj("items");
%>

<%-- create a new data store --%>
<proxy:createstore store="assets" />
<%
// go through each incoming item
for (int i = 0; i < list.length(); i++) {
     JSONObject item = (JSONObject)list.get(i);%>

     <%-- Register the current external content item as a proxy asset --%>
     <proxy:register externalid='<%=item.getString("id") %>'
     type="Dummy"
     name='<%=item.getString("title") %>'
     varname="internalid" />

<%-- Add the proxy asset to the datastore --%>
<proxy:addstoreitem store="assets"
                    id='<%=ics.GetVar("internalid") %>'
                    type="Dummy" />
<%
}
// put store name in request scope
request.setAttribute("store", "assets");
request.setAttribute("total", Integer.valueOf(list.length()));
%>
</cs:ftcs>

48.3.4.3 グリッド・ウィジェット用のデータ・ストアの作成

この手順では、UIウィジェットに送り返すJSONをレンダリングします。この手順は、CustomElements/Dummy/UI/Data/Search/SearchJson内で実行されます。

これは、次の例で示すように、proxy:tojsonユーティリティ・タグで実行します。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ taglib prefix="proxy" uri="futuretense_cs/proxy.tld"%>
<cs:ftcs>
<proxy:tojson store="${store}" total="${total}" />
</cs:ftcs>

48.3.4.4 カスタム検索のテスト

JSONのスクリプトを記述したら、検索機能が完全に動作することをテストします。検索をテストするには、次の手順を実行します。

  1. Contributorインタフェースで、検索ボックスから「検索タイプ」としてDummyを選択します。「検索」アイコンをクリックします。

    図48-5 Dummyアセットを表示する検索ドロップダウン

    図48-5の説明が続きます
    「図48-5 Dummyアセットを表示する検索ドロップダウン」の説明

  2. 「検索」タブが開き、関連データが表示されます。

  3. サムネイル表示に切り替えると、次のようになります。

    図48-7 サムネイル表示の検索結果

    図48-7の説明が続きます
    「図48-7 サムネイル表示の検索結果」の説明

    「検索」タブは、ドッキング・モードでも機能します。ツールチップには、デフォルト・データが記載されます。

    図48-8 ドッキングされたパネル内の検索結果

    図48-8の説明が続きます
    「図48-8 ドッキングされたパネル内の検索結果」の説明

48.3.4.5 追加のカスタマイズ

この項では、ここまでに説明した内容を超えて実装可能なカスタマイズについて説明します。これらのカスタマイズを使用していなくても、カスタム検索は実装できます。

サムネイルのレンダリング

この例では、Dummyリポジトリは、各コンテンツ・アイテムのサムネイル・イメージへのURLを返します。

サムネイルをレンダリングするために、Dummyリポジトリから送信されるサムネイルのURLを取得するように変更を加えます。これが行われるようにするには、サムネイル表示(ドッキングされている場合とドッキングされていない場合)のグリッドをカスタマイズする必要があります。つまり、次の構成エレメントをオーバーライドすることになります。

UI/Layout/CenterPane/Search/View/ThumbnailView
UI/Layout/CenterPane/Search/View/DockedThumbnailView

それぞれの構成ファイルは、次のように作成する必要があります。

CustomElements/Dummy/UI/Layout/CenterPane/Search/View/ThumbnailViewConfig
CustomElements/Dummy/UI/Layout/CenterPane/Search/View/DockedThumbnailViewConfig

ThumbnailViewConfig構成ファイルには、次のXML構成を含めます。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld" %>
<%@ taglib prefix="xlat" uri="futuretense_cs/xlat.tld" %>
<cs:ftcs>
  <thumbnailviewconfig>
    <formatter>fw.ui.GridFormatter.simpleThumbnailFormatter</formatter>
  </thumbnailviewconfig>
</cs:ftcs>

これにより、Dummyのサムネイル表示用のformatter設定をオーバーライドしていることがわかります(その他のグローバル構成エレメントの設定は維持されます)。このformatterは、サムネイル・イメージを表示する検索結果ごとのデフォルト・ビューと、名前フィールド(調査リンク)をレンダリングします。

同様に、ドッキングされたサムネイル表示の設定は、CustomElements/Dummy/UI/Layout/CenterPane/Search/View/に、次のXMLを含むDockedThumbnailViewConfigを作成することでオーバーライドする必要があります。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
<cs:ftcs>
<ics:callelement element=
"[CustomElements/Dummy/UI/Layout/CenterPane/Search/View/ThumbnailViewConfig]" />
</cs:ftcs>

注意:

検索構成の詳細は、第III部「Contributorインタフェースのカスタマイズ」を参照してください。

エレメント名を囲む大カッコは、そこに指定されているエレメント名のカスタマイズ済バージョンを、ics:callelementタグで検索する必要がないことを示しています。


グリッド・コンテキスト・メニューの構成

アセット操作の一部は、プロキシ・アセットには適用されません。そのため、デフォルトのグリッド・コンテキスト・メニュー設定をオーバーライドする必要があります。エレメントUI/Config/GlobalHtmlをオーバーライドするために、MyConfigという名前の新しいエレメントをUI/Configに作成します。MyConfigの作成方法の詳細は、第65.5.3項「コンテキスト・メニューのカスタマイズ」を参照してください。

このようにすることで、グローバル設定はオーバーライドした設定にマージされないようになります。

フィールドのソート

外部コンテンツ・ソースのAPI機能によっては、一部のフィールドに対するソート機能が使用できないことがあります。この場合は、デフォルトのコンテキスト・メニュー構成ファイルをオーバーライドすることで、ソート・ドロップダウン・メニューをカスタマイズできます。これを処理するには、次の構成ファイルを作成します。

CustomElements/Dummy/UI/Layout/CenterPane/Search/View/SearchTopBarConfig

さらに、次のXMLコードを使用します(ここでは、名前によるソートのみが使用できると仮定しています)。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ taglib prefix="xlat" uri="futuretense_cs/xlat.tld"%>
<cs:ftcs>
<sortconfig>
  <sortfields>
    <sortfield id="name_asc">
      <fieldname>name</fieldname>
      <displayname>
          <xlat:stream key="UI/UC1/Layout/NameSort1" escape="true"/> 
      </displayname>
      <sortorder>ascending</sortorder>
    </sortfield>
    <sortfield id="name_desc">
      <fieldname>name</fieldname>
      <displayname>
          <xlat:stream key="UI/UC1/Layout/NameSort2" escape="true"/> 
      </displayname>
      <sortorder>descending</sortorder>
    </sortfield>
  </sortfields>
</sortconfig>
</cs:ftcs>

SearchTopBarConfigエレメントとContextMenuConfigエレメントは、図48-9に示すように、どちらもエレメントのresdetails1 (またはresdetails2)フィールドにmerge=falseを設定しておく必要があります。

図48-9 構成ファイルのエレメントの詳細値フィールド

図48-9の説明が続きます
「図48-9 構成ファイルのエレメントの詳細値フィールド」の説明

48.3.5 カスタム・ツリーの実装

カスタム・ツリーを使用すると、図48-10に示すように、ユーザーはカテゴリごとに簡単に外部コンテンツを参照できるようになります。

図48-10 カスタム・ツリー

図48-10の説明が続きます
「図48-10 カスタム・ツリー」の説明

ツリーをレンダリングするために、次の2つのエレメントを作成します。

  • Dummy/Tree/Root: ツリーのルート・ノードをレンダリングします。これらのノードは、コンテンツの各カテゴリになります。

  • Dummy/Tree/Load: 特定のカテゴリに属するコンテンツをすべてレンダリングします。

カスタム・ツリーを実装するには、最初にカスタム・ツリー・タブを登録してから、カスタム・ツリーのコードを実装する必要があります。

この項の内容は、次のとおりです。

48.3.5.1 カスタム・ツリー・タブの登録

カスタム・ツリー・タブは、「新規ツリー・タブの追加」ページで定義します。この例で作成するタブでは、Proxy Assetsという新しいコンテンツ・ツリーを作成します。このツリーには、Dummy/Tree/Rootを参照する単一のカスタム・セクション(Dummy)を含めます。

この例のカスタム・ツリー・タブを登録するには、次の手順を実行します。

  1. Adminインタフェースで、「管理」タブを選択して、「ツリー」をダブルクリックします。

    「ツリー・タブ」ページが開きます。

  2. 「ツリー・タブ」ページの下側にある、「新規ツリー・タブの追加」をクリックします。

    「新規ツリー・タブの追加」ページが開きます(図48-11)。

    図48-11 「新規ツリー・タブの追加」ページ

    図48-11の説明が続きます
    「図48-11 「新規ツリー・タブの追加」ページ」の説明

  3. 必要に応じて、各フィールドに入力します。この例では、次のようにフィールドに入力します。

    • タイトル: タブのタイトルとしてProxy Assetsを入力します。

    • サイト: リストから「プロキシ」を選択します。

    • 必須ロール: リストから「任意」を選択します。

    • タブ・コンテンツ: 「Dummy」を選択してから、「選択したアイテムの追加」をクリックして、その項目を「選択済」列に移動します。「選択済」列の項目は、「Dummy」のみにする必要があります。

    • セクション名: フィールドに、Dummyと入力します。

    • エレメント名: フィールドに、Dummy/Tree/Rootと入力します。

  4. 各フィールドに適切な値を入力したら、「保存」をクリックしてアセットを保存します。

48.3.5.2 ツリーのコードの実装

Dummy/Tree/Rootでは、外部リポジトリを問い合せてツリーのルート・ノード(この例では、カテゴリのリスト)を取得します。その後で、ツリー・ノードのデータがカテゴリごとに生成されます。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ taglib prefix="satellite" uri="futuretense_cs/satellite.tld"%>
<%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
<%@ page import="org.codehaus.jettison.json.*"%>
<cs:ftcs>

<%-- Retrieve all categories from dummy repository --%>
<ics:setvar name="serviceURL" value="/browse/categories.json" />
<ics:callelement element="Dummy/GetData" />

<%
JSONArray list = (JSONArray)ics.GetObj("items");
for (int i = 0; i < list.length(); i++) {
     String category = (String)list.get(i);
     // 1) build a tree node id - needs to be unique
     // Note: we need to make sure that AssetType is not present in the scope
     // (BuildTreeNodeID is otherwise assuming the tree node to be an asset node)
     %>
     <ics:removevar name="AssetType" />
     <ics:callelement element="OpenMarket/Gator/UIFramework/BuildTreeNodeID" >
          <ics:argument name="AdHoc" value='<%=category %>' />
     </ics:callelement>
     <%
     // 2) build the 'LoadURL' i.e. the URL to call to load this node's children
     // OpenMarket/Gator/UIFramework/LoadTab is a standard element. 
     // Required input is:
     // - populate: the element rendering tree nodes to execute
     // - op: must be set to 'load'
     //
     // We're also passing 'category' which is required by our custom logic in 
     // Dummy/Tree/Load
     //
     %>
     <satellite:link assembler="query"
                       pagename="OpenMarket/Gator/UIFramework/LoadTab"
                       outstring="LoadURL">
     <satellite:argument name="populate" value="Dummy/Tree/Load"/>
     <satellite:argument name="op" value="load"/> 
     <satellite:argument name="category" value='<%=category %>' />
     </satellite:link>

     <ics:callelement element="OpenMarket/Gator/UIFramework/BuildTreeNode">
          <ics:argument name="Label" value='<%=category %>' />
     </ics:callelement>
<%}%>
</cs:ftcs>

このコードは、次のツリーを生成します。

図48-12 生成されたカスタム・ツリー

図48-12の説明が続きます
「図48-12 生成されたカスタム・ツリー」の説明


注意:

OpenMarket/Gator/UIFramework/BuildTreeNodeIDエレメントとOpenMarket/Gator/UIFramework/BuildTreeNodeエレメントは、どちらもICSスコープ内の変数を利用します。<ics:callelement />タグはグローバル・スコープを持つため、<ics:removevar />を使用して、特定の変数をICSスコープから明示的に削除(永久的または一時的)することが必要になる場合があります。


Dummy/Tree/Loadでは、外部サービスを問い合せて、特定のカテゴリに含まれるすべてのコンテンツを取得して、コンテンツ・アイテムごとにノードをレンダリングします。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
<%@ taglib prefix="proxy" uri="futuretense_cs/proxy.tld"%>
<%@ page import="org.codehaus.jettison.json.*"%>
<cs:ftcs>

<%-- Retrieve all content for a given category --%>
<ics:setvar name="serviceURL" value='<%="/browse/" + ics.GetVar("category") +
   ".json"%>' />
<ics:callelement element="Dummy/GetData" />

<%
JSONArray list = (JSONArray)ics.GetObj("items");

for (int i = 0; i < list.length(); i++) {
     JSONObject item = (JSONObject)list.get(i);%>

     <proxy:register externalid='<%=item.getString("id") %>'
                     type="Dummy"
                     name='<%=item.getString("title") %>'
                     varname="internalid" />

     <ics:callelement element="OpenMarket/Gator/UIFramework/BuildTreeNodeID">
        <ics:argument name="AssetType" value="Dummy" />
        <ics:argument name="ID" value='<%=ics.GetVar("internalid") %>' />
     </ics:callelement>

     <ics:callelement element="OpenMarket/Gator/UIFramework/BuildTreeNode">
        <ics:argument name="Label" value='<%=item.getString("title") %>' />
        <ics:argument name="Description" value='<%=item.getString("title") %>' />
        <ics:argument name="executeFunction" value="inspect" />
     </ics:callelement>
     <%
}
%>
</cs:ftcs>

その後、各カテゴリを参照できます。図48-13に示すように、各カテゴリを参照できるようになります。

図48-13 カスタム・ツリーのオブジェクトの参照

図48-13の説明が続きます
「図48-13 カスタム・ツリーのオブジェクトの参照」の説明

ノードをダブルクリックすると、そのノードについてのデフォルトのプロキシ・アセット調査ページが開きます。

48.4 Webページへのプロキシ・アセットの埋込み

この項の内容は、次のとおりです。

48.4.1 プロキシ・アセット用テンプレートの作成

プロキシ・アセット用のテンプレートは、その他のアセット・タイプのテンプレートと同じように定義できます。ここまでの例に使用してきたDummyアセットは、図48-14に示す方法でテンプレートを定義できます。

図48-14 定義済のSummaryテンプレート

図48-14の説明が続きます
「図48-14 定義済のSummaryテンプレート」の説明

すべてのテンプレートに対して、「使用」には、「エレメントはレイアウトとして使用されます。」がリスト表示されている必要があります。「エレメントはHTMLページ内で使用されます。」を選択していると、作成したテンプレートは、ページ・アセットの作成中に、ContributorのUIに表示されなくなります。

プロキシ・アセット用テンプレートの作成には、通常、2つの個別のアクションが必要になります。まず、(内部)アセットIDを指定して、外部IDを取得します。その次に、サード・パーティのリポジトリAPIを使用して、コンテンツ・メタデータを取得します。

Dummyアセットに固有の例として、次のコードを実装します。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ taglib prefix="asset" uri="futuretense_cs/asset.tld"%>
<%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
<%@ taglib prefix="render" uri="futuretense_cs/render.tld"%>
<%@ page import="com.sun.jersey.api.client.*"%>
<%@ page import="com.sun.jersey.api.client.config.*"%>
<%@ page import="org.codehaus.jettison.json.*"%>
<cs:ftcs>
<render:logdep cid='<%=ics.GetVar("tid")%>' c="Template"/>

<%-- first, retrieve the external id --%>
<asset:load name="asset" type='<%=ics.GetVar("c") %>'
       objectid='<%=ics.GetVar("cid") %>' />
<asset:get name="asset" field="name" />
<asset:get name="asset" field="externalid" />

<%
// given the external content id, invoke the  third-party repository API
// to retrieve content metadata
Client client = Client.create();
WebResource res = client.resource("http://localhost:7001/sites/samples/content/" +
     ics.GetVar("externalid") + ".json");
ClientResponse resp = res.accept("application/json").get(ClientResponse.class);
JSONObject data = new JSONObject(resp.getEntity(String.class));
%>
<%-- finally render content metadata --%>
<h4><%=data.getString("title") %></h4>
<p><%=data.getString("foo") %></p>
<img src="<%=data.getString("image") %>" alt="<%=data.getString("title") %>" />
</cs:ftcs>

48.4.2 プロキシ・アセットのスロットでの使用

プロキシ・アセットは、標準アセットに適用されるものとまったく同じタグと原則を使用して、ページ内に埋込みできます。これについては、図48-15を参照してください。

図48-15 埋込みプロキシ・アセットの例

図48-15の説明が続きます
「図48-15 埋込みプロキシ・アセットの例」の説明

次に示すコード例では、ページ・アセットに、Dummyアセットを受け入れるdummyAttributeというページ属性があると仮定しています。

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
<%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
<%@ taglib prefix="render" uri="futuretense_cs/render.tld"%>
<%@ taglib prefix="insite" uri="futuretense_cs/insite.tld"%>
<%@ taglib prefix="assetset" uri="futuretense_cs/assetset.tld"%>
<cs:ftcs><render:logdep cid='<%=ics.GetVar("tid")%>' c="Template"/>
<html>
<head>
     <title>Proxy test page</title>
</head>
<body>
     <assetset:setasset name="page" id='<%=ics.GetVar("cid") %>'
                        type='<%=ics.GetVar("c") %>' />
     <assetset:getattributevalues attribute="dummyAttribute" listvarname="dummy"
                        name="page" typename="PageAttribute" />
     <ics:listget listname="dummy" fieldname="value" output="id" />
     <h3>Proxy Test Page</h3>
     <insite:calltemplate field="dummyAttribute" c='Dummy'
                        cid='<%=ics.GetVar("id") %>' tname="Summary" />
</body>
</html>
</cs:ftcs>

48.4.3 プロキシ・アセットのキャッシング

レンダリング済のコンテンツは独立したリポジトリで保管および管理されるため、コンテンツが変更されたときに(コンテンツが変更された後でも)、その変更をWebCenter Sitesが認識する方法がありません。

このため、プロキシ・アセットをレンダリングするテンプレート(第48.4.1項「プロキシ・アセット用テンプレートの作成」で定義したSummaryテンプレートなど)には、期間が限られたキャッシュ有効期限を設定するようにしてください。