intra-mart Accel Platform ポートレット プログラミングガイド 第12版 2021-04-01

4. ポートレットの開発(スクリプト開発編)

4.1. 概要

この章では、スクリプト開発モデルを利用してポートレットの作成を行うための手順や注意事項を説明します。
ポートレットを作成するためには、「ポートレットのライフサイクル」の内容を理解し、どのライフサイクルを利用するのかを決定する必要があります。
  1. 画面開発 (render サイクル)

    ポートレットに表示する画面を作成します。モードやウィンドウステータスを判定して切り替えることも可能です。
    表示モード用の画面は必ず必要です。
  2. アクション処理 (processAction サイクル)

    ポートレットからサブミットされたデータの処理を作成します。作成されたファンクションコンテナは、Action ハンドラと呼ばれ、ポートレット編集画面で登録することによって利用できます。
    また、Event を設定することによって、別のポートレットと連携することも可能です。
  3. イベント処理 (processEvent サイクル)

    他のポートレットから発生したイベントの受信処理を作成します。作成されたファンクションコンテナは、Event ハンドラと呼ばれ、ポートレット編集画面で登録することによって利用できます。
    Action ハンドラで Event を設定された場合のみ実行されます。

ポートレットのライフサイクルごとに、以下のように作成するファイルが異なります。

render 必須 スクリプト開発モデルの画面。プレゼンテーションページとファンクションコンテナ。
processAction 任意 handleAction ファンクションを実装したファンクションコンテナ。
processEvent 任意 handleEvent ファンクションを実装したファンクションコンテナ。
全てのライフサイクル用プログラムを作成し、組み合わせることで1つのポートレットとして作成することも可能です。
ライフサイクルごとに別々に開発を行って、複数のポートレット間で組み合わせて利用できるように作成することも可能です。
次項より、ポートレットで利用可能な API と、各ライフサイクルでの実装方法について簡単に説明していきます。

4.2. ポートレットAPI

単純な画面表示のみのポートレットでは、ポートレットAPIを利用しなくても作成可能ですが、ポートレットの機能を最大限に利用するためには、ポートレット API を利用する必要があります。
特に Action 処理や Event 処理を行うためには、ポートレット API を利用しなくては実行できません。
このドキュメントでは、基本的な関数のみに絞って説明します。全ての API については「ポータル API リスト」を参照してください。

4.2.1. PortalManager

ポートレットの機能を利用するための、さまざまな関数を提供します。
それぞれの関数については、次項以降で実際に利用する際に説明します。

4.3. ポートレットモード

スクリプト開発モデルで作成されたポートレットのポートレットタイプは、「スクリプト開発モデルポートレット」です。
ポートレットモードの利用可否はポートレットタイプごとに設定され、「スクリプト開発モデルポートレット」の初期状態では、表示モードと編集モードが利用できます。

4.3.1. ポートレットモードの設定

ポートレット定義を変更し、ポートレットを初期化することでポートレットモードの設定を変更できます。
  • ポートレット定義の変更
    ポートレットモードの設定は以下のファイルで管理されています。intra-mart Accel Platform を停止して設定後、再起動を行います。
    設定ファイル
    %CONTEXT_PATH%/WEB-INF/plugin/jp.co.intra_mart.portal.portlets.jssp_8.0.0/plugin.xml
    設定箇所
    <?xml version="1.0" encoding="utf-8"?>
    <plugin>
       <extension point="jp.co.intra_mart.portal.portlets">
          <portlet
              id="jp.co.intra_mart.portal.portlets.jssp"
              name="PresentationPagePortlet"
              display-name="%display-name"
              description="%description"
              version="8.0.0"
              rank="1">
               <portlet-class>jp.co.intra_mart.foundation.portal.portlets.model.PresentationPagePortlet</portlet-class>
               <expiration-cache>0</expiration-cache>
               <supports>
                   <mime-type>text/html</mime-type>
                   <portlet-mode>VIEW</portlet-mode>
                   <portlet-mode>EDIT</portlet-mode>
                   <!-- ここにモードを追加 -->
               </supports>
               ...
          </portlet>
       </extension>
    </plugin>
    

4.3.2. ポートレットモードの取得

API を利用して、以下のように現在のポートレットモードを取得できます。
ポートレットモードは小文字で取得されますので、注意してください。

(ex.) view, edit, help

var renderRequest = PortalManager. getRenderRequest();
var portletMode = renderRequest. getPortletMode();

4.4. ウィンドウステータス

4.4.1. ウィンドウステータスの取得

API を利用して、以下のように現在のポートレットモードを取得できます。
ウィンドウステータスは小文字で取得されますので、注意してください。
また、最小化時にはポートレットが呼び出されませんので、「minimized」が取得されることはありません。

(ex.) normal, maximized, minimized

var renderRequest = PortalManager. getRenderRequest();
var windowState = renderRequest. getWindowState();

4.5. 画面開発 (renderサイクル)

render サイクルでは、通常の Web ページと同様に画面表示が行われます。
スクリプト開発モデルの画面は、おおむね通常の intra-mart の画面開発と変わりません。
ポートレット新規登録/編集画面(「ポータル グループ管理者操作ガイド」参照)で設定されたページ引数は、init 関数の request オブジェクトより取得できます。
また、次項アクション処理、イベント処理によって設定されたページ引数も、同様にinit関数のrequestオブジェクトより取得できます。

4.5.1. RenderRequest

ポートレットで利用する request オブジェクトは、通常の Web ページのリクエストは異なり、ポートレット専用のrequest オブジェクトを利用します。
このリクエストを利用することで、ポートレットの情報を取得できます。
  • RenderRequest の取得

    var renderRequest = PortalManager.getRenderRequest();
    
    ただし、通常の Webページと共用できるように、ページ引数は、init 関数の request オブジェクトを利用して取得することも可能です。
  • ページ引数の取得

    function init(request) {
      var renderRequest = PortalManager.getRenderRequest();
      // value1 と value2 は同じ値
      var value1 = request.param1;
      var value2 = renderRequest.param1;
    }
    

    RenderRequest から、現在のポートレットモード、ウィンドウステータスなどが取得できます。

4.5.1.1. RenderRequestのスコープ

RenderRequest は通常の Web アプリケーションのリクエストとスコープが異なります。
全てのポートレットで独立したリクエストを保持しており、ポータル画面を表示する際のリクエストパラメータを引き継ぎません。
ただし以下のパラメータは、ポートレットコンテナにより、自動的に設定されます。
portal_cd ポートレットが配置されているポータル画面のキー。
portalKind

ポートレットが配置されているポータル画面のポータル種別。以下の値が取得される。

user ユーザポータル
group グループポータル
ポートレットにリクエストパラメータを設定するためには、アクション処理またはイベント処理を実行する必要があります。
また、一度設定したリクエストパラメータは、セッションが持続する間、再度アクション処理またはイベント処理が実行されるまで有効です。

4.5.2. ActionURL, RenderURL

スクリプト開発モデルで作成されたポートレットからサブミット処理を行い、 処理終了後に再びポータル画面を表示する機能を作成する場合には、ポートレットコンテナと通信するため、以下の URL に対してサブミットする必要があります。
ActionURL Action 機能を呼び出す URL
RenderURL ポータル画面を再表示するための URL
これらは、PortalManager を利用して取得できます。
  • ActionURL, RenderURL の取得

    var actionURL = PortalManager.createActionURL();
    var renderURL = PortalManager.createRenderURL();
    
以下に、スクリプト開発モデルで開発されたポートレットでサブミットされた後に、アクション処理を呼び出すサンプルを示します。
  1. ファンクションコンテナ

    // ActionURL
    var actionURL = "";
    function init(request) {
      //  ActionURL を取得する
      actionURL  =  PortalManager.createActionURL();
    }
    
  2. プレゼンテーションページ

    <!-- ActionURL を指定 -->
    <form name="sampleActionForm" action="<IMART type="string" value=actionURL></IMART>" method="POST">
      <!-- アクション処理で使用する値 -->
      <INPUT type="text" name="param1" value="">
      <INPUT type="submit" value="実行">
    </form>
    • ポータル画面の表示には、「portal/desktop」というパスが割り振られています。
      そのため、このサービスID-URLにサブミットすることでもポータル画面の再表示が可能ですが、その場合ポータル情報を引き継ぐことができませんので、上記の方法を利用するようにしてください。
    • アクション処理を呼び出すためには、ActionURL にサブミットする以外にありません。
      ポートレット管理画面で Action ハンドラを登録し、プレゼンテーションページで ActionURL にサブミットするようにしてください。
      Action ハンドラが未定義の場合、単純にポータル画面を再表示します。
    • ActionURL はポータル情報を含むため、データ量が多くなります。メソッドは POST を指定するようにしてください。

4.5.3. 通常の画面とポートレット画面を共用するには

共用するコードと通常の画面のみ必要なコードを別々のプレゼンテーションページとして作成し、通常の画面用のプレゼンテーションページでは、include タグを利用して共用ページを読み込みます。
ただし、include タグではリクエストパラメータは引き継がれませんので、別途変数を定義して個別に引き継ぐ必要があります。
また、このような利用を行う場合はポートレットの各 API は利用できませんので注意してください。

【ポートレット画面と共用する通常画面のプレゼンテーションページ】

<html>
<head>

  <link src="sample.css" type="text/css">

</head>
<body>
  <div>
        ヘッダ表示情報
  </div>
  <!-- 共用コードをインクルードする -->
  <!-- param1, param2 引き継ぐリクエストパラメータ -->
  <IMART type="include" page="sample/sample-portlet"
param1=value1
param2=value2
/>
  <div>
        フッタ表示情報
  </div>
</body>
</html>

4.6. アクション処理 (processActionサイクル)

processAction サイクルでは画面表示がありませんので、ファンクションコンテナのみ作成します。
さらにポートレット管理画面で作成した Action ハンドラを登録し、ActionURL へサブミットすることでアクション処理が実行されます。
アクション処理では、RenderParameter の設定、PortletPreference の設定、イベントの設定などの更新処理を行います。

4.6.1. Actionハンドラの作成

以下にイベントを設定する Action ハンドラの例を示します。

  1. ファンクションコンテナを作成し、以下の関数を定義します。

    (このファンクションコンテナを Action ハンドラと呼びます。)

    (ex.) sample/portal/sample_action.js

    // 「handleAction」という名前で関数を定義する。
    function handleAction(request, response) {
      // リクエスト引数を取得
      var value = request.param1;
      // イベントを設定 ( キー: "event1"、値: value )
      response.setEvent("im_event1", value);
    }
    
    • Action ハンドラは、render で利用するファンクションコンテナに記述しても構いません。
      また、Java で作成された Action ハンドラクラスを利用することもできます。
    • 以下のような値を return することでもイベントを発生させることができます。

      Object プロパティのキーと値をペアとするイベント
      その他 文字列として判断し、キーと値が同じイベント

      ただし、IM 用ポートレットに対するイベントを発生させるためには、 ‘im_’ で始まるキーを指定する必要があります。

    • response.setEvent()で設定する値については、「ポータルAPI リスト」の ActionResponse を参照してください。

  2. Action ハンドラをポートレットに登録します。

    portlet_regist_jssp

    <ポートレット新規登録画面>

  3. 画面開発 (renderサイクル) 」で作成した画面をポータル画面に配置し、ポートレットからアクション処理を呼び出します。

    Actionハンドラ実行後に、画面を再表示します。

    portlet_action_jssp

    <ポータル画面 - アクション処理>

4.6.2. ActionRequest, ActionResponse

Action ハンドラの引数、request, response は、それぞれ ActionRequest オブジェクト、ActionResponse オブジェクトです。
これらのオブジェクトを利用することにより、リクエスト引数を取得したり、イベントを設定したりできます。
詳細は、「ポータル API リスト」を参照してください。

4.6.3. RenderParameterの設定

画面表示時に取得可能なリクエストパラメータ(RenderParameter)は、アクション処理またはイベント処理の中で設定を行います。
アクション処理呼び出し時のリクエストパラメータは、ActionRequestに格納されていますが、 renderサイクルには引き継がれないため 、必要な場合は明示的に設定する必要があります。
また、アクション処理の呼び出し時には過去に設定された RenderParameter は全てクリアされています。

(ex.) processAction サイクルでの RenderParameter の設定

// RenderParameter を設定する場合。
response.setRenderParameter("param1", "value1");
// RenderParameter を削除する場合。
response.setRenderParameter("param2", null);

(ex.) render サイクルでの RenderParameter の利用

String value = request.param1;

4.6.4. イベントの設定

イベントを設定することにより、アクション処理を受け付けたポートレット以外の複数のポートレットにイベントの発生を通知して処理を引き渡すことが可能です。

(ex.) processAction サイクルでのイベントの設定

response.setEvent(eventId, eventValue);

4.6.5. 利用可能なActionハンドラ

intra-mart Accel Platform では、以下の Action ハンドラが標準で用意されています。
これらは、Java 言語で実装されたクラスですが、スクリプト開発でも利用できます。

4.6.5.1. jp.co.intra_mart.foundation.portal.common.handler.DefaultPortletHandler

ポートレット新規登録/編集画面で、Action ハンドラチェックボックスにチェックを行うと、初期値としてこの Actionハンドラが設定されます。
この Action ハンドラは、リクエストパラメータから値を取得して、そのキーと値を用いてイベントを発生させます。
単純に画面からイベントを発生させたいだけの場合、Action ハンドラを作成せずに、このハンドラを利用できます。
イベントを発生させるためには、以下のリクエストパラメータを設定します。
  • “portlet.event.” + 任意の文字列

    これにより、以下のイベントが作成されます。

    プロパティ名 内容
    id リクエストパラメータキーの任意の文字列
    value リクエストパラメータの値

    リクエストパラメータに複数設定することで、複数のイベントを発生させることも可能です。

4.6.5.2. jp.co.intra_mart.foundation.portal.common.handler.SetRenderParameterHandler

ポータル画面表示時のリクエストパラメータは、ポートレットとスコープが異なるため、ポートレット内の処理からは取得できません。
この Action ハンドラを設定することで、ポータル画面表示時のリクエストパラメータをポートレットで利用できます。

4.7. イベント処理 (processEventサイクル)

processEvent サイクルでは画面表示がありませんので、ファンクションコンテナのみ作成します。
さらにポートレット管理画面で作成した Event ハンドラを登録し、任意のポートレットのアクション処理でイベントが設定されることにより、イベント処理が実行されます。
イベント処理では、RenderParameter の設定、PortletPreference の設定、イベントの設定などの更新処理を行います。

4.7.1. Eventハンドラの作成

以下に RenderParameter を設定する Event ハンドラの例を示します。

  1. ファンクションコンテナを作成し、以下の関数を定義します。

    (このファンクションコンテナを Event ハンドラと呼びます。)

    (ex.) sample/portal/sample_event.js

    // 「handleEvent」という名前で関数を定義する。
    function handleEvent(event, request, response) {
      // イベント情報を取得
      var eventId = event.id;
      var value = event.value;
      // 画面表示に利用するリクエストパラメータを設定
      response.setRenderParameter(eventId, value);
    }
    
    • Event ハンドラは、render で利用するファンクションコンテナに記述しても構いません。
      また、Java で作成された Event ハンドラクラスを利用することもできます。
  2. Event ハンドラをポートレットに登録します。

    portlet_regist2_jssp

    <ポートレット新規登録画面>

  3. 画面開発 (renderサイクル) 」で作成した画面と「 アクション処理 (processActionサイクル) 」で作成したイベントを呼び出すことができる
    ポートレットをポータル画面に配置し、イベントを設定するポートレットからアクション処理を呼び出します。

    アクション処理からEventハンドラが呼ばれ、その後に画面を再表示します。

    portlet_action2_jssp

    <ポータル画面 - イベント処理>

4.7.2. EventRequest, EventResponse

Event ハンドラの引数、request, response は、それぞれ EventRequest オブジェクト、EventResponse オブジェクトです。
これらのオブジェクトを利用することにより、リクエスト引数を取得したり、さらにイベントを設定したりできます。

詳細は、「ポータル API リスト」を参照してください。

4.7.3. Eventオブジェクト

Event ハンドラの第 1 引数は、アクション処理で設定されたイベント情報オブジェクトです。以下の情報を格納しています。
プロパティ名
id String
アクション処理で設定されたイベント ID
省略された場合、文字列「ImEvent」が設定される。
value String
アクション処理で設定されたイベントの値
オブジェクトを設定した場合も文字列として取得される。
source String Event を設定したポートレットのポートレットコード

4.7.4. RenderParameterの設定

画面表示時に取得可能なリクエストパラメータ(RenderParameter)は、アクション処理またはイベント処理の中で設定を行います。
イベント処理呼び出し時に設定済みであった RenderParameter は、EventRequest に格納されており、特に処理を行わない限り、 render サイクルに自動的に引き継がれます。 引継ぎが不要な場合は明示的に削除する必要があります。

(ex.) processEvent サイクルでの RenderParameter の設定

// RenderParameter を設定する場合。
response.setRenderParameter("param1", "value1");
// RenderParameter を削除する場合。
response.setRenderParameter("param2", null);

(ex.) render サイクルでの RenderParameter の利用

request.getParameter(eventId);

4.7.5. イベントの設定

イベントを設定することにより、イベント処理を受け付けたポートレット以外の複数のポートレットにイベントの発生を通知して処理を引き渡すことが可能です。
ただし、イベント処理でさらにイベント処理を行うとパフォーマンスの低下をまねき、またイベントループの発生する可能性もありますので、十分注意して実装してください。

(ex.) processEvent サイクルでのイベントの設定

response.setEvent(eventId, eventValue);

4.8. 「重要なお知らせ」ポートレットについて

ポータルモジュールには、汎用的な新着情報を表示する「重要なお知らせ」ポートレットが用意されています。
この「重要なお知らせ」ポートレットでは、新着情報として以下の項目を表示します。
  • 新着情報の種類を示すためのカテゴリ
  • 新着情報の内容(概要)
  • 配信日付
  • 新着情報に紐付く遷移先の情報(リンク)
「重要なお知らせ」ポートレットはJavaEE開発モデルを利用して作成されていますが、スクリプト開発モデルで利用できるようにインタフェースが用意されています。
「重要なお知らせ」ポートレットに独自の新着情報を表示させるためには、下記の手順で新着情報を追加します。
  1. 新着情報を取得するプロバイダを実装する。
    「重要なお知らせ」ポートレットに表示される情報の配列を取得する以下のファンクションを実装したファンクションコンテナを作成します。
    • ファンクション名 : getNewArrivedList

    • パラメータ

      パラメータ名 内容
      user String ユーザ ID
      group String ログイングループ ID
      properties Object 設定ファイルに定義された、初期パラメータ

      このファンクションは、以下の新着情報オブジェクトの配列を返却する必要があります。

    • 新着情報オブジェクト

      プロパティ 内容
      category String 新着情報の種類を示すためのカテゴリ
      contents String 新着情報の内容(概要)
      url String 新着情報の詳細情報へ遷移する URL(リンク)
      popup Boolean 詳細情報へ遷移する際にポップアップするかどうかのフラグ
      date String 新着情報の配信日付(システム日時)

    <sample_provider.js>

    // getNewArrivedList 関数を実装します。
    function getNewArrivedList(user, group, properties) {
      // 新着情報の配列を作成します。
      var values = new Array();
      for (var i = 0; i < result.countRow; i++) {
        values[i] = new Object();
        values[i].category = result.data[i].category;        // 新着情報の種類を示すためのカテゴリ
        values[i].contents = result.data[i].contents;        // 新着情報の内容(概要)
        values[i].date  =  result.data[i].arrived_date;      // 配信日付
        values[i].url  =  result.data[i].url;                // 新着情報に紐付く遷移先の情報(リンク)
        values[i].popup = ("1" == result.data[i].popup);     // リンクへ参照時にポップアップを呼び出すかどうか
      }
      // 新着情報の配列を返却します。
      return values;
    }
    
  2. プロバイダの実装を定義する。
    実装したプロバイダクラスについての情報は、%PUBLIC_STORAGE_PATH%/portal/system_notice.xml に 以下の情報を定義します。

    <プロバイダ設定ファイル>

    要素 説明
    new-arrived-portlet/sort 取得した新着情報をカテゴリでソートするかどうかを定義します。
    new-arrived-portlet/provider/provider-class プロバイダの実装クラス。固定です。
    new-arrived-portlet/provider/init-param
    新着情報を取得するファンクションコンテナを「pagePath」パラメータに定義します。
    それ以外の任意のパラメータを設定して、ファンクションコンテナで利用できます。

    たとえば、上記のスクリプト開発モデルプログラムより新着情報を取得するプロバイダを使って新着情報を取得する場合は、以下のように定義を行います。

    <system_notice.xml>

    <new-arrived-portlet>
      <sort>true</sort>
        :
        :
      <provider>
            <!--  スクリプト開発モデル用のプロバイダクラス。固定とする  -->
            <provider-class>
                jp.co.intra_mart.foundation.portal.general_purpose_portlet.provider.PageBaseCallProvider
            </provider-class>
            <init-param>
                <!--  プロバイダを定義する  -->
                <param-name>pagePath</param-name>
                <param-value>/hoge/sample_provider.js</param-value>
            </init-param>
      </provider>
    </new-arrived-portlet>
    
    プロバイダを複数登録して、複数の新着情報を1つのポートレットに表示することも可能です。