Jetspeedデコレーターへの導入

デコレーターとは 動的に作成されるフラグメント(画面の一部分)の周りを囲むもので 静的もしくは、半静的な マークアップランゲージで記述できるものと 定義されます。デコレーターは、 通常 Velocityテンプレートもしくは、JSPテンプレートとして書かれます。このガイドでは、主に Velocity スクリプト言語で デコレーターを作成する方法について書きます。しかし、ここに書かれる 標準的な方法とアプローチ手段は、大体の所、 他のスクリプト言語で、デコレーションを作成する際にも応用可能です。

ページを構築する際に使用するデコレーションの種類にはポートレットとレイアウト(ページ)の2つがあります。

ポートレットのデコレーションとは Jetspeed のウインドウの装飾にあたります。これは、個々のポートレットフラグメントの HTML (XHTML, VXML, etc) で表示されるコンテンツ部分を囲むもので、適切なタイトルの表示や、ウインドウの状態やポートレットのモードの変化と連携して変わるボタン群の表示を担当します。

レイアウトもしくはページのデコレーションとは、1つPSMLファイルを元に表される1つのポータルページの ヘッダー部分とフッター部分の装飾を提供するものです (参考: PSMLについての更なる情報については、PSMLを扱ってデザインをする人のための資料) 。これらのデコレーションは、ページとポートレットの一般的なスタイル情報を持ちます。ポートレット内部のスタイル情報は、デコレーターのスタイル情報によって上書きされます。

デコレーションのファイル構成

全てのデコレーション用のファイルは、webアプリケーションのルートディレクトリの直下にあるdecorationsというディレクトリに保存されます。このディレクトリの下の 重要な2つのディレクトリが、レイアウト装飾用のlayoutディレクトリとポートレット装飾用のportletディレクトリです。個別のデコレーションは、これら2つのディレクトリの下に、それぞれ独自のディレクトリを持ちます。Jetspeedは、layoutportlet の下に あなたが に作成するディレクトリの名称で、デコレーターファイルの場所を特定します。では、これが どういう仕組みで働くかについての 更なる詳細をこのガイドの続き で見ていきましょう。

レイアウト(ページ) デコレーションの詳細

一言でいうと 4つのファイル

もっとも基本的な形で レイアウトのデコレーションをするのであれば、4つのファイルを定義するだけです。:

  • decorator.properties
  • styles.css
  • header.vm
  • footer.vm

この中の3つのファイル;decorator.properties, header.vm, と footer.vm は、/decorations/layoutの下に作成したディレクトリに直接置いてください。styles.css は、あなた作ったデコレーションのサブディレクトリ css/ に入れます。[訳注:すなわち/YOUR_WEB_APP/decorations/layout/YOUR_DECORATION_NAME/cssディレクトリにスタイルシートを置く。]

レイアウト デコレーションの基本設定: decorator.properties

The decorator.properties file holds basic information about your layout decoration. In all actuallity, this file can be blank, but we still require that it be present as it is used by other APIs to "discover" available decorations. With that being said, it is safe to assume that all the properties defined below are optional.

decorator.properties ファイルは、あなたのレイアウト デコレーションの基本情報を保持します。実際のところ、このファイルは 空白でも構いませんが、他のAPIが使用可能なデコレーションを探すのに使用されるためファイル自体は存在する必要があります。ということで、下の定義にあるプロパティは 全てオプションであると仮定しても問題ありません。

Property NameDescriptionDefault
base.css.class この値は、一般的に ヘッダーのテンプレートファイルの一番上の要素タグの中に 配置されます。ヘッダーテンプレート作成の説明のところで、この使用方法を 見ることになります。 あなたのデコレーション名がデフォルト値となります。
stylesheet デコレーションのスタイルシートへの相対パス css/styles.css
header デコレーションのヘッダーテンプレートへの相対パス header.vm
footer デコレーションのフッターテンプレートへの相対パス footer.vm

自分専用のページトップ: header.vm

ファイルheader.vmは、あなたのポータルページのトップ部分を表します。機能的なヘッダーテンプレートを記述すのに必要になる基本事項について 以下に 各セクションごとに 書いてあります。



注意:前提事項として、読者は、HTMLとCSSについての十分な知識があると仮定してあります。デコレーションを開発するに当たって、基本的なVelocityの知識は、あれば良いくらいで、必須の知識ではありません。

        
<html>
   <head>
     #defineLayoutObjects()

上の最初の2行の意味は明らかでしょう、もし そうでない場合は、これ以降の内容は あまり あなたの助けにならないでしょう。^^)

最初のマクロ: #defineLayoutObjects()

さて、#defineLayoutObjects()を含む行ですが、これは、前の2行ほどは その目的について意味が あまり明らかではありません。#defineLayoutObjects()は、いわゆる Velocityの世界で マクロと 言われるものです。マクロは、事前に定義された Velocityの小さなコードで、Velocityテンプレートの中で再利用されます。これから使用する全てのグローバル マクロ(このマクロも含む)は、WEB-INF/jetspeed_macros.vmで定義されています。後ほど、 このガイドの中で、もし あなたが そうしたいのであれば、自分のデコレーションを作成するにあたって便利であるカスタムマクロの作成方法について議論します。では、#defineLayoutObjects()にもどりましょう。#defineLayoutObjects()は、様々な値をVelocityに対して追加し、それらは、header.vm, footer.vm,他のマクロと そして全てのポートレット デコレーション テンプレートの内部でアクセス可能になります。ここで、#defineLayoutObjects()に関する話を 簡単にやめることはできますが、Velocityをまだはじめたことがない人のために Velocityの内部の動きを見ていく方が 助けになる気がします。では 余計な事をいうのはこれくらいにして、コードは、こうなっています。

        
  #macro (defineLayoutObjects)
    #set($preferedLocale = $JS2RequestContext.locale)
    #set($rootFragment = $jetspeed.currentFragment)
    #set($site = $request.getAttribute("org.apache.jetspeed.portalsite.PortalSiteRequestContext"))
    #set($theme = $request.getAttribute("org.apache.jetspeed.theme"))
    #set($layoutDecoration = $theme.getDecoration($rootFragment))
  #end        

むむ、この中ではいったい何がおきているのでしょうか?さて、1行目には、#set()があります。これは Velocityで指示子と呼ばれるものです。指示子は オリジナルの関数であり マクロではありません。#set()は、非常にわかりやすいですね。イコール記号の 右辺にある値を 受け取り 左辺へ 割り当てるものです。素晴らしい、これは、かなりわかりやすいですね。しかし、どうやってこの値を取り扱えばいいのでしょうか?いったい$JS2RequestContext.localeは、どこから現れたのでしょう?では、すこしだけ戻って、Velocityのオブジェクトをどうやって使うか書きたいと思います。全てのVelocityテンプレートで利用可能なオブジェクトは、$someObjectという書き方で参照することができます。メソッドの実行は、$someObject.getFoo() の様に書くことで 実行できます。getFoo()を実行してみましょう。実にすばらしいことに、引数を取らないgetterメソッドは、$someObject.fooという風に書けます。この$JS2RequestContextに関していうと、これは、org.apache.jetspeed.RequestContext のインスタンスでVelocityで使用できるように、、Jetspeedによってインスタンス化されます。そして、org.apache.jetspeed.RequestContextの Javadoc を見るとわかりますが、$JS2RequestContext.localeは、現在のポートレットのユーザのロケールとなる、java.util.Localeのインスタンスを渡してくれます。これ以上は シンプルにはできないでしょう?



次に 出てくるのは、#set($rootFragment = $jetspeed.currentFragment) という別の set の行ですね。今回は、$rootFragment と呼ばれるものを作成していすね。これは、org.apache.jetspeed.om.page.ContentFragment のインスタンスです。$jetspeed.currentFragmentが何をするのかは、このガイドでは、重要ではないので、飛ばして 先に進みます。





#set($site = $request.getAttribute("org.apache.jetspeed.portalsite.PortalSiteRequestContext"))

#set($theme = $request.getAttribute("org.apache.jetspeed.theme"))


おお、$requestです。やっと親しみのあるものが出てきました。これは、実際にjavax.servlet.http.HttpServletRequestのインスタンスで、我々はここから Jetspeedから Velocityに 渡された オブジェクトを取り出します。本当のオブジェクトは、それぞれ org.apache.jetspeed.portalsite.PortalSiteRequestContextorg.apache.jetspeed.decoration.Theme です。もうちょっと後で これら全てのオブジェクトのよい利用方法を見ていきます。

ヘッダーを作る:ヘッダータグの適切なコーディング方法

このセクションでは、レイアウトデコレーションの<HEAD>タグを適切にコーディングするための情報を書きます。では、さっそく コードを見てみましょう。

  
<html>
    <head>
     #defineLayoutObjects()
     
     <base href="#BaseHref()">
     <meta http-equiv="Content-type" content="#ContentType()" />
     <meta http-equiv="Content-style-type" content="text/css" />   
     #includeJavaScriptForHead()
     #IncludeStylesheets()    
     <title>#PageTitle()</title>
     <meta name="description" content="#PageDescription()" />
<base>タグ

最初に、 <base href="#BaseHref()">から始めましょう。これは、WEBのリソースの場所の解決をするためのベースを定義する際に使用します。 <base>についての深い議論については、W3C Schools Referenceを見てください。もしすでにあなたが Jetspeed で遊んだ経験があるのであれば、一貫した html やスタイルシートへのパスを取得するのを妨げる、幾通りもの非常にややこしい URL リライトの問題に気づくでしょう。BASEタグを定義することにより、この問題は全て解決されます。#BaseHref()マクロに関していうと、これは、単に あなたのWEBアプリケーションのルートディレクトリへの絶対パスを作成します。実際のコードは、サーブレットAPIを使って記述するとこうなります。:

HttpServletRequest request;
StingBuffer baseHref = new StringBuffer(request.getScheme())
     .append("://").append(request.getServerName())
	 .append(":").append(request.getServerPort())
	 .append(request.getContextPath()).append("/");
return baseHref.toString();		 

Velocityマクロのコードは もう少し簡潔になります。^^)

${request.scheme}://${request.serverName}:${request.serverPort}${request.contextPath}/
メタタグ: <meta http-equiv="Content-type" content="#ContentType()" />

は  text/htmlと、UTFの様な適切なエンコードの種類を返します。

#includeJavaScriptForHead()

  このガイドを書いている今の時点では、オリジナルのJetspeed 2サーバを実行させるためには、ほとんど Java Scriptを書く必要はありません。しかし、今後、設定機能や管理機能でAJAXを利用しようと考えているので近い将来変わるかもしれません。