オリジナルのZPTとの違い

Freyja ZPTエンジンは基本的にオリジナルのZPTの仕様に従っていますが、 いくつかの違いがあります。 ここでは、オリジナルの仕様との相違点について説明します。

オリジナルのZPT仕様の詳細についてはZPTのサイトにある 以下のドキュメント等を参照して下さい。

ZPT全般

  • 式の評価結果の真偽判定においては、以下のいずれかに合致した場合に偽と みなします。それ以外は真とみなします。
    • 評価対象が変数であるが値が存在しない
    • nullである
    • java.lang.BooleanインスタンスでかつFALSEと同値である
    • java.lang.Numberインスタンスでかつ値が0である
    • 配列でかつ長さが0である
    • java.util.Collectionインスタンスでかつ空である
    • java.util.Enumerationインスタンスでかつ残りの要素がない
    • java.util.Iteratorインスタンスでかつ残りの要素がない
    • toString()の値の長さが0である

TAL属性

  • 名前空間はサポートしていません。指定しても無視されます。
  • tal:on-errorで利用できるエラーオブジェクトが異なります。 Freyja ZPTエンジンでは以下のオブジェクトが利用可能です。
    type
    発生したjava.lang.Throwableのクラス名
    value
    発生したjava.lang.Throwableオブジェクト
    traceback
    スタックトレース文字列
  • [Freyja拡張] tal:conditionで空文字列を式として与えた場合は偽と評価されます。
  • tal:repeatでは、式の評価結果が配列またはjava.util.Collectionである場合は それらの持つ要素について処理が繰り返されます。nullまたは値が存在しない 場合は一度も繰り返されません。それ以外の場合は評価結果自身について一度だけ 処理が行なわれます。
  • tal:repeatで繰り返し変数のプロパティ「Letter」は「LETTER」と表記する 必要があります。また、以下のプロパティは未サポートです。
    • roman
    • Roman

TAL式

  • 次の変数が組み込み変数として利用できます。
    名前
    nothing null
    null null
    default net.skirnir.freyja.zpt.DefaultクラスのSingletonオブジェクト
    CONTEXTS グローバル変数が格納されたjava.util.Mapオブジェクト
    true java.lang.Boolean.TRUE
    false java.lang.Boolean.FALSE
    request javax.servlet.http.HttpServletRequestオブジェクト
    response javax.servlet.http.HttpServletResponseオブジェクト
    session javax.servlet.http.HttpSessionオブジェクト。セッションが生成されていない場合は未定義
    application javax.servlet.ServletContextオブジェクト
    locale リクエストを処理する際のLocaleオブジェクト
    element 現在処理中のタグに関する情報を持つnet.skirnir.freyja.zpt.ElementInfo型のオブジェクト。tal:defineでグローバル変数にelementをコピーしておき、タグの評価が終わった後に evaluatedプロパティを参照することでタグ全体の評価結果を取得することができます。またElementInfo#toString()はevaluatedプロパティの値を返すので、例えばグローバル変数aにelementをコピーしておいた状態でタグの評価後に <div tal:replace="structure a"></div>のようにすることでタグの評価結果を描画することができます [1.0.11以上]
    attrs 現在処理中のタグの評価前の属性を持つMapオブジェクト。キーは名前(String)。値はnet.skirnir.freyja.Attributeオブジェクト [1.0.11以上]

    また変数ではありませんが負でない整数を書いた場合、その数値を表す java.lang.Integerのオブジェクトとみなされます。

    以下の変数は未サポートです。

    • options
    • root
    • here
    • container
    • template
    • user
    • modules
  • [Freyja拡張] 複数のセグメントからなるPath式を評価する時、セグメントの 評価値が偽である場合は次のセグメントを評価しますが、 セグメントの区切り記号として「||」を使用すると、 セグメントの評価値がnullのときのみ次のセグメントを評価します。
  • Nocall式は式の値を加工しません。「nocall:」をつけない場合と同じ挙動をします。
  • Python式はサポートしていませんが、range関数だけは対応しています。 range関数は引数を1つまたは2つとることができます。

    range(to)形式では、0からto(TAL式)の評価結果までの数値からなるInteger型の配列を返します。

    range(from, to)形式では、from(TAL式)の評価結果からto(TAL式)の評価結果までの数値からなるInteger型の配列を返します。

    fromもtoも評価結果はNumber型か、toString()の結果が整数として解釈できる文字列になるようなオブジェクトである 必要があります。そうでない場合は値は0とみなされます。 またtoの評価結果はfromの評価結果と同じか大きくなければいけません。そうでない場合はrange()の値はIntegerの空の配列になります。

  • [Freyja拡張] Java式をサポートしています。具体的には、「java:」をつけること でJavaの式を記述することができます(Tigerの記法には対応していません)。 Java式の中ではいくつかの組み込み関数が利用可能です。 利用可能な組み込み関数についてはJava式で利用可能な組み込み関数を参照して下さい。
  • [Freyja拡張] Page式をサポートしています。 「page:<コンテキストパス相対のURI>」という式を、URIにコンテキスト パスを補完して必要に応じてセッションIDを付加したURLに変換します。 URIにはリクエストパラメータを付与することもできます。 また、URIの途中やリクエストパラメータの中に String式のような$...という置換指定を記述することもできます。 リクエストパラメータの中に記述された置換指定は、値をURLエンコードした上で埋め込まれます。
  • [Freyja拡張] Include式をサポートしています。 「include:<コンテキストパス相対のURI>」という式を、 指定されたURIが指すページの内容に置き換えます。 これはJSPの<jsp:include>に相当します。
  • [Freyja拡張] IncludeBody式をサポートしています。 「include-body:<コンテキストパス相対のURI>」という式を、 指定されたURIが指すページの<body>タグの内容(<body>タグ自身は含みません) に置き換えます。
  • [Freyja拡張] I18npage式をサポートしています。 「i18npage:<コンテキストパス相対のURI>」と記述します。 URIの拡張子の前に、現在のロケールから決定された(Javaのプロパティファイル形式の) 接尾辞を付加する以外はPage式と同じです。接尾辞は現在のロケールと同一になるのでは なく、URI+ロケールに対応するリソースが存在するものに変換されることに注意して下 さい。 例えば/image/title_ja.jpgが存在して/image/title_ja_JP.jpgが存在しない場合、 ロケールが「ja_JP」であっても最終的なURIは/image/title_ja.jpgになります。

Path式

Path式の扱いに関して詳しく説明します。

最初のセグメントの解決手順

Path式の最初のセグメント(「first/second/third」の「first」の部分) は次の順序に従って解決されます。

  1. 組み込み変数であれば変数の値。
  2. HttpServletRequest#getAttribute("first")の値がnullでなければその値。
  3. セッションが張られていてかつHttpSession#getAttribute("first")の値がnullでなければその値。
  4. ServletContext#getAttribute("first")の値がnullでなければその値。
  5. HttpServletRequest#getParameter("first")の値がnullでなければその値。
  6. 上記のいずれにも該当しない場合はnull。
セグメントの解釈

例えばPath式で「self/name」と書いた場合、selfを解決した結果である オブジェクトについてセグメント「name」を解釈した結果が最終結果になります。

セグメントは基本的にはオブジェクトのプロパティと解釈されます。 したがって、例えば上記の例ではselfに対応するオブジェクトについて getName()メソッドを呼び出した結果が最終結果になります。

オブジェクトの型によっては以下のような特別な解釈がなされます。 解釈は以下の表の上から順に適用され、結果がnullでExceptionがスローされなければさらに下の解釈が適用されます。

オブジェクトの型 解釈
java.util.Collection セグメントが「size」である場合、Collection#size()の
結果。
配列型 セグメントが「length」である場合、配列の長さ。
java.lang.String セグメントが「length」である場合、文字列の長さ。
java.util.Date セグメント文字列中の「%」を「/」に置き換えたものをフォー
マット文字列として日時を現在のロケールに従ってフォーマッ
トした結果。例えばオブジェクトの表す日時が1983年1月14日
でセグメント文字列が「yyyy%MM%dd」である場合、結果は
「1983/01/14」となる。
全ての型 セグメント文字列をオブジェクトのプロパティ名とみなす。
オブジェクトのプロパティの値が結果となる。該当するプロパ
ティが存在しない場合はnull。