<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <title>ZPTテンプレート</title>
    <link rel="stylesheet" href="/css/style.css" type="text/css" media="all" />
    
    
  </head>
  <body>
    <div class="header">
      <div id="pane.left-header" class="pane left">
        <div id="org.seasar.kvasir.cms.toolbox.customPop-2" class="pop org.seasar.kvasir.cms.toolbox.customPop">
          <div class="body"><div class="wiki">
<ul>
<li><a href="/" class="pageNotFound">（サイトトップ）</a></li>
<li><a href="/download">ダウンロード</a></li>
<li><a href="/news/" class="pageNotFound">新着情報</a></li>
<li><a href="/docs/" class="pageNotFound">ドキュメント</a></li>
</ul>
</div>
</div>
        </div>
      </div>
      <div id="pane.right-header" class="pane right">
        <div id="org.seasar.kvasir.cms.toolbox.loginPop-1" class="pop org.seasar.kvasir.cms.toolbox.loginPop">
          <div class="body">
<form method="post" action="/plugins/toolbox/login.do/docs/1.0.x/ref/zptTemplate">
    <div class="row">
      <span class="label">Name</span>
      <span class="textinput"><input type="text" name="name" size="12" value="" /></span>
    </div>
    <div class="row">
      <span class="label">Password</span>
      <span class="textinput"><input type="password" name="password" size="12" value="" /></span>
    </div>
    <div class="row">
      <span class="submit"><input type="submit" value="Login" /></span>
    </div>
</form>
</div>
        </div><div id="org.seasar.kvasir.cms.pop.loginUserPop-1" class="pop org.seasar.kvasir.cms.pop.loginUserPop">
          <div class="body"></div>
        </div>
      </div>
    </div>
    <div class="page-frame">
      <div id="pane.left-sidebar" class="pane sidebar-frame sidebar subcontent">
        <div id="org.seasar.kvasir.cms.toolbox.searchPop-1" class="pop org.seasar.kvasir.cms.toolbox.searchPop">
          <h2 class="title">Search</h2>
          <div class="body"><form class="simple" method="get" action="/plugins/toolbox/search.do">
  <input type="text" name="query" size="12" />
  <input type="submit" value="Go!" />
</form>
</div>
        </div><div id="org.seasar.kvasir.cms.toolbox.customPop-1" class="pop org.seasar.kvasir.cms.toolbox.customPop">
          <h2 class="title">メニュー</h2>
          <div class="body"><ul>
  <li><a href="/" class="pageNotFound">（サイトトップ）</a></li>
  <li><a href="/download">ダウンロード</a></li>
  <li><a href="/news">新着情報</a></li>
  
    
    
      <li>
        <a href="/docs/1.0.x/user">ユーザマニュアル</a>
        <ul>
          <li>
            <a href="/docs/1.0.x/user/description">Ymirとは</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/processFlow">Ymirの処理フロー</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/projectStatus">動作ステータス</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/generator">自動生成機能</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/vili">Eclipseプラグイン「Vili（ヴィリ）」</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/ve">Eclipseプラグイン「Ve（ヴェー）」</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/setUp">セットアップ</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/skeleton">空のアプリケーション</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/example">サンプルアプリケーションの作成</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/development">開発における注意点</a>
            
          </li><li>
            <a href="/docs/1.0.x/user/faq">FAQ</a>
            
          </li>
        </ul>
      </li><li>
        <a href="/docs/1.0.x/ref">リファレンスマニュアル</a>
        <ul>
          <li>
            <a href="/docs/1.0.x/ref/pageClass">Pageクラス</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/pathMapping">リクエストパスとPageクラスのマッピング</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/response">レスポンス</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/fileupload">ファイルアップロード</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/typeConversion">型の自動変換</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/zptTemplate">ZPTテンプレート</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/constraintCheck">制約チェック</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/validation">バリデーション</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/transactionToken">トランザクショントークン</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/permissionCheck">権限チェック</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/objectScope">オブジェクトスコープ</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/i18n">国際化</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/exceptionHandler">例外処理</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/include">インクルード</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/conversation">カンバセーション</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/appProperties">アプリケーションの設定</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/dicon">diconファイルの扱い</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/standardArchitecture">アプリケーションアーキテクチャ標準</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/ymirJson">JSON連携</a>
            
          </li><li>
            <a href="/docs/1.0.x/ref/batch">バッチプログラムの作成</a>
            
          </li>
        </ul>
      </li><li>
        <a href="/docs/1.0.x/dev">Ymir開発者マニュアル</a>
        <ul>
          <li>
            <a href="/docs/1.0.x/dev/build">Ymirのビルド</a>
            
          </li><li>
            <a href="/docs/1.0.x/dev/release">Ymirのリリース</a>
            
          </li><li>
            <a href="/docs/1.0.x/dev/update-ymir-fragment-dbflute">DBFluteフラグメントの更新</a>
            
          </li>
        </ul>
      </li><li>
        <a href="/docs/1.0.x/etc">その他</a>
        
      </li><li>
        <a href="/docs/1.0.x/glossary">用語集</a>
        <ul>
          <li>
            <a href="/docs/1.0.x/glossary/Vili">Vili</a>
            
          </li><li>
            <a href="/docs/1.0.x/glossary/ve">Ve</a>
            
          </li>
        </ul>
      </li>
    
  
  <li><a href="/roadmap">ロードマップ</a></li>
  <li><a href="https://www.seasar.org/issues/browse/YMIR">既知の不具合を閲覧する・不具合を報告する</a></li>
  <li><a href="https://www.seasar.org/svn/ymir/">SVNリポジトリ</a></li>
  <li><a href="http://svn.seasar.org/browse/?root=ymir">SVNリポジトリを閲覧</a></li>
</ul>
</div>
        </div>
      </div>
      <div id="pane.main" class="pane main">
      
        <div id="org.seasar.kvasir.cms.toolbox.breadcrumbsPop-1" class="pop org.seasar.kvasir.cms.toolbox.breadcrumbsPop">
          
          <div class="body"><ul>
  <li class="first"><a href="/">(TOP)</a></li><li><a href="/docs">ドキュメント</a></li><li><a href="/docs/1.0.x">ドキュメント（1.0.x系）</a></li><li><a href="/docs/1.0.x/ref">リファレンスマニュアル</a></li><li>ZPTテンプレート</li>
</ul>
</div>
        </div><div id="org.seasar.kvasir.cms.pop.contentPop-1" class="pop org.seasar.kvasir.cms.pop.contentPop">
          <h2 class="title">ZPTテンプレート</h2>
          <div class="body">
<ul class="information">
  
  <li>2009-12-09 14:35:58</li>
</ul>
<div class="content"><div class="document">
<p>Ymirでの標準のビューテンプレート記述言語はZPT（Zope Page Template）です。ZPTエンジンとしてSkirnirプロジェクトから公開されているタグベーステンプレートエンジン構築フレームワーク<a class="reference" href="http://www.skirnir.net/product/freyja/">Freyja</a>（フレイヤ）に含まれているZPT実装（以下単にFreyjaと呼びます）を使っています。</p>
<p>Freyjaは基本的にオリジナルのZPTの仕様に従っていますが、いくつかの違いがあります。Freyjaの実装とオリジナルの仕様との相違点についてはFreyjaのドキュメントを参照して下さい。</p>
<ul>
<li><a class="reference" href="http://www.skirnir.net/product/freyja/zpt/reference-difference.html">Freyjaのドキュメント</a></li>
</ul>
<p>なおオリジナルのZPT仕様の詳細については<a class="reference" href="http://wiki.zope.org/ZPT/FrontPage">ZPTのサイト</a>にある</p>
<ul>
<li><a class="reference" href="http://wiki.zope.org/ZPT/TALSpecification14">TAL Specification 1.4</a></li>
<li><a class="reference" href="http://wiki.zope.org/ZPT/TALESSpecification13">TALES Specification 1.3</a></li>
<li><a class="reference" href="http://wiki.zope.org/ZPT/MetalSpecification11">METAL Specification 1.1</a></li>
</ul>
<p>を参照して下さい。</p>
<p>以下ではYmirでだけ有効なFreyjaの拡張仕様について説明します。</p>
<div class="section" id="e7b584e381bfe8bebce381bfe5a489e695b0">
<h3><a name="e7b584e381bfe8bebce381bfe5a489e695b0">組み込み変数</a></h3>
<p>Ymirでは次の変数が組み込み変数として追加されています。</p>
<table border="1" class="docutils">
<colgroup>
<col width="13%" />
<col width="87%" />
</colgroup>
<thead valign="bottom">
<tr>
<th>名前</th>
<th>値</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>ymirRequest</td>
<td>org.seasar.ymir.Requestオブジェクト</td>
</tr>
<tr>
<td>container</td>
<td>org.seasar.framework.container.S2Containerオブジェクト</td>
</tr>
<tr>
<td>messages</td>
<td>メッセージリソースが格納されているorg.seasar.ymir.message.Messagesオブジェクト</td>
</tr>
<tr>
<td>token</td>
<td>トランザクショントークンを扱うためのorg.seasar.ymir.token.Tokenオブジェクト。詳しい使い方については「<a class="reference" href="/docs/1.0.x/ref/transactionToken">トランザクショントークン</a>」を参照のこと</td>
</tr>
<tr>
<td>notes</td>
<td>制約違反のメッセージを保持するorg.seasar.ymir.message.Notesオブジェクト</td>
</tr>
<tr>
<td>variables</td>
<td>その時点での変数空間を表すnet.skirnir.freyja.VariableResolverオブジェクト。この組み込み変数を使うことで、例えば変数名をnameという名前で定義しておき、<tt class="docutils literal"><span class="pre">variables/?name</span></tt>として動的な変数名から値を取得することができる</td>
</tr>
<tr>
<td>param-self</td>
<td>リクエストパラメータとPageオブジェクトを表すオブジェクト（Ymir-1.0.2以降）。例えば<tt class="docutils literal"><span class="pre">param-self/name</span></tt>というTAL式は、「リクエストパラメータにnameという名前のパラメータがあればその値、なければPageオブジェクトのnameプロパティの値」というように評価されます。param-selfを使うと、フォーム画面で「初期表示はPageオブジェクトのプロパティ値を表示するが、バリデーションエラー時にはユーザによって入力された値を表示する」というケースにおいて、<tt class="docutils literal"><span class="pre">param-self/name</span></tt>のようにZPTをシンプルに記述することができます。</td>
</tr>
</tbody>
</table>
<div class="section" id="e789b9e588a5e381aarequeste382b9e382b3e383bce38397e382aae38396e382b8e382a7e382afe38388">
<h4><a name="e789b9e588a5e381aarequeste382b9e382b3e383bce38397e382aae38396e382b8e382a7e382afe38388">特別なrequestスコープオブジェクト</a></h4>
<p>Ymirでは以下のオブジェクトがrequestスコープにバインドされています。</p>
<table border="1" class="docutils">
<colgroup>
<col width="15%" />
<col width="85%" />
</colgroup>
<thead valign="bottom">
<tr>
<th>名前</th>
<th>値</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>self</td>
<td>処理対象のPageオブジェクト。リクエストパスに対応するPageコンポーネントが存在しない場合は未定義</td>
</tr>
</tbody>
</table>
<p>したがって、例えばPageオブジェクトのtitleプロパティの値を参照したい場合は「self/title」と書けばよいことになります。</p>
</div>
</div>
<div class="section" id="talese381aepathe5bc8f">
<h3><a name="talese381aepathe5bc8f">TALESのPath式</a></h3>
<p>ここではYmirにおけるTALESのPath式の扱いに関して説明します。</p>
<div class="section" id="e69c80e5889de381aee382bbe382b0e383a1e383b3e38388e381aee8a7a3e6b1bae6898be9a086">
<h4><a name="e69c80e5889de381aee382bbe382b0e383a1e383b3e38388e381aee8a7a3e6b1bae6898be9a086">最初のセグメントの解決手順</a></h4>
<p>Path式の最初のセグメント（「first/second/third」の「first」の部分） は次の順序に従って解決されます。</p>
<ol>
<li>&quot;first&quot;の部分が正の数値文字列であれば文字列をIntegerに変換した値。</li>
<li>&quot;first&quot;の部分が&quot;CONTEXTS&quot;であれば組み込み変数CONTEXTSの値。</li>
<li>tal:defineやtal:repeatで生成された変数スコープに&quot;first&quot;という変数があればその値。変数スコープは一番近いものから外側に向けてグローバル変数スコープまで検索される。</li>
<li>&quot;first&quot;の部分がFreyjaの組み込み変数名（nothing、null、default、CONTEXTS、true、false、request、response、session、application、locale、element、attrs、repeat）であれば組み込み変数の値。</li>
<li>HttpServletRequest#getAttribute(&quot;first&quot;) の値がnullでなければその値。</li>
<li>セッションが張られていてかつHttpSession#getAttribute(&quot;first&quot;) の値がnullでなければその値。</li>
<li>ServletContext#getAttribute(&quot;first&quot;) の値がnullでなければその値。</li>
<li>&quot;first&quot;の部分がYmirの組み込み変数名（ymirRequest、container、messages、token、variables）であれば変数の値。</li>
<li>HttpServletRequest#getParameter(&quot;first&quot;) の値がnullでなければその値。</li>
<li>HttpServletRequest#getAttribute(&quot;self&quot;)の値がnullでなく、かつその値オブジェクトが&quot;first&quot;という名前のプロパティを持てばその値。</li>
<li>上記のいずれにも該当しない場合はnull。</li>
</ol>
</div>
<div class="section" id="e382bbe382b0e383a1e383b3e38388e381aee8a7a3e98788">
<h4><a name="e382bbe382b0e383a1e383b3e38388e381aee8a7a3e98788">セグメントの解釈</a></h4>
<p>例えばPath式で「self/name」と書いた場合、selfを解決した結果であるオブジェクトについてセグメント「name」を解釈した結果が最終結果になります。</p>
<p>セグメントは基本的にはオブジェクトのプロパティと解釈されます。したがって、例えば上記の例ではselfに対応するオブジェクトについてgetName()メソッドを呼び出した結果が最終結果になります。</p>
<p>オブジェクトの型によっては特別な解釈がなされますが、Ymirではさらに以下のような解釈が行なわれます。解釈は以下の表の上から順に適用され、結果がnullでExceptionがスローされなければさらに下の解釈が適用されます。</p>
<table border="1" class="docutils">
<colgroup>
<col width="40%" />
<col width="60%" />
</colgroup>
<thead valign="bottom">
<tr>
<th>オブジェクトの型</th>
<th>解釈</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>org.seasar.ymir.message.Messages</td>
<td>
<p>セグメントが「%」で始まる場合、「%」を除いた文字列を引数としてgetMessage()を呼び出した結果。そうでない場合はセグメント文字列を引数としてロケールなしでgetProperty()を呼び出した結果。</p>
<p>結果がnullである場合はMessageNotFoundRuntimeExceptionがスローされる。</p>
</td>
</tr>
<tr>
<td>org.seasar.kvasir.util.collection.I18NPropertyReader</td>
<td>セグメントが「%」で始まる場合、「%」を除いた文字列を引数として現在のロケールについてgetProperty()を呼び出した結果。そうでない場合はセグメント文字列を引数としてロケールなしでgetProperty()を呼び出した結果。</td>
</tr>
<tr>
<td>org.seasar.kvasir.util.collection.PropertyReader</td>
<td>セグメント文字列を引数としてgetProperty()を呼び出した結果。</td>
</tr>
<tr>
<td>org.seasar.kvasir.util.collection.AttributeReader</td>
<td>セグメント文字列を引数としてgetAttribute()を呼び出した結果。</td>
</tr>
<tr>
<td>org.seasar.ymir.message.Notes</td>
<td>セグメントが「size」である場合、Notes#size()の結果。「size(XXX)」の形である場合、「XXX」の部分の文字列を引数としてNotes#size(String)を呼び出した結果。「categories」である場合、Notes#categories()の結果。それ以外の場合、セグメント文字列をNotesのカテゴリ文字列とみなして、そのカテゴリに属するNoteが存在するならNotes#get(カテゴリ文字列)の返り値。</td>
</tr>
<tr>
<td>org.seasar.ymir.message.Note</td>
<td>セグメントが「%value」である場合、Note#getValue()の返り値をキーとして現在のロケールについてメッセージリソースを検索した結果のメッセージ文字列。メッセージ文字列が見つからなかった場合はMessageNotFoundRuntimeExceptionがスローされる。詳細については<a class="reference pageNotFound" href="/docs/1.0.x/ref/i18n#notese382aae38396e382b8e382a7e382afe38388e38292e4bdbfe381a3e3819fe383a1e38383e382bbe383bce382b8e69687e5ad97e58897e381aee6a78be7af89">Notesオブジェクトを使ったメッセージ文字列の構築</a>を参照のこと。</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="decoratee5bc8fefbc88ymir-1-0-7e4bba5e9998defbc89">
<h4><a name="decoratee5bc8fefbc88ymir-1-0-7e4bba5e9998defbc89">decorate式（Ymir-1.0.7以降）</a></h4>
<p>decorate式はtal:attributesの中でclass属性の値を設定するためだけに利用できる式で、以下の構文で記述します:</p>
<pre class="literal-block">
decorate:*条件* with *[!]class属性に追加する値*
</pre>
<p>この式の値は、条件が真の場合は指定された値を現在のclass属性に追加したものになります。指定された値が既にclass属性の値に含まれている場合は何もしません。条件が偽の場合は、この式の値は現在のclass属性の値になります。</p>
<p>「条件」にはtal:conditionに書くような条件式を書くことができます。</p>
<p>「class属性に追加する値」には文字列で値を書いて下さい。</p>
<p>なお値の直前に「!」をつけると、既存のclass属性が置換されます。例えば項目「date」を表すinputタグについて、バリデーションエラーの時に動的にclass属性に「error」という値を追加するための記述例は以下の通りです:</p>
<pre class="literal-block">
&lt;input type=&quot;text&quot; name=&quot;date&quot; tal:attributes=&quot;class decorate:notes/contains(date) with error&quot; /&gt;
</pre>
</div>
<div class="section" id="decorate-by-notese5bc8fefbc88ymir-1-0-7e4bba5e9998defbc89">
<h4><a name="decorate-by-notese5bc8fefbc88ymir-1-0-7e4bba5e9998defbc89">decorate-by-notes式（Ymir-1.0.7以降）</a></h4>
<p>decorate-by-notes式はdecorate式とほぼ同じですが、メッセージ（Notes）表示に特化しています。具体的には、decorate式の条件部に「notes/contains(NAME)」と書く代わりに単に「NAME」と書くことができます（逆に、普通の条件式を書くことはできません。）:</p>
<pre class="literal-block">
decorate-by-notes:[*カテゴリ名*] with *[!]class属性に追加する値*
</pre>
<p>「カテゴリ名」で指定されたカテゴリに属するNoteが現在のNotesに存在する場合に、指定された値がclass属性に追加されます。</p>
<p>カテゴリ名は省略することができます。省略した場合、現在のNotesになんらかのメッセージが存在する場合に指定された値がclass属性に追加されます。例えば項目「date」を表すinputタグについて、バリデーションエラーの時に動的にclass属性に「error」という値を追加するための記述例は以下の通りです:</p>
<pre class="literal-block">
&lt;input type=&quot;text&quot; name=&quot;date&quot; tal:attributes=&quot;class decorate-by-notes:date with error&quot; /&gt;
</pre>
</div>
</div>
<div class="section" id="e3819de381aee4bb96">
<h3><a name="e3819de381aee4bb96">その他</a></h3>
<ul>
<li><tt class="docutils literal"><span class="pre">org.seasar.ymir.zpt.SessionIdEmbeddingInterceptor</span></tt>のコンポーネント定義をapp.diconやymir++.diconに追加することで、ZPTテンプレート中の「action」「href」「src」属性に書いたページ相対URL（「.」「./～」「..」「../～」形式のURL）に必要に応じて自動的にセッションIDが付与されるようになります（Ymir-1.0.2以降）。なお、ymir-skeleton-generic-1.0.2以降で生成したYmirプロジェクトには<tt class="docutils literal"><span class="pre">ymir++.dicon</span></tt>にこのコンポーネント定義が記述されていますので、この機能が有効になっています。必ずCookieが利用できる前提であるケースやセッションを利用しないケースなど、この機能が不要な場合は<tt class="docutils literal"><span class="pre">ymir++.dicon</span></tt>からこのコンポーネント定義を除去しても構いません。</li>
</ul>
</div>
</div>
</div>
</div>
        </div>
      
    </div>
    </div>
    <div class="footer-delimiter"></div>
    <div id="pane.footer" class="pane footer">
      <div id="org.seasar.kvasir.cms.pop.poweredByPop-1" class="pop org.seasar.kvasir.cms.pop.poweredByPop">
        <div class="body">Powered by Kvasir/Sora</div>
      </div>
    </div>
  </body>
</html>
