<?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>インクルード</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/include">
    <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>インクルード</li>
</ul>
</div>
        </div><div id="org.seasar.kvasir.cms.pop.contentPop-1" class="pop org.seasar.kvasir.cms.pop.contentPop">
          <h2 class="title">インクルード</h2>
          <div class="body">
<ul class="information">
  
  <li>2009-02-13 13:05:00</li>
</ul>
<div class="content"><div class="document">
<p>Ymirではあるページの中に別のページ断片をインクルードして利用することができるようになっています。また、単にページ断片をインクルードするだけでなく、主となるページに関連付けられたPageクラスの処理時にページ断片に関連付けられたPageクラスの処理を併せて呼び出せるようになっています。このため、再利用可能な共通画面部品のようなものを作成することもできます。</p>
<p>以下、テンプレートエンジンとしてZPTエンジンを使う場合のインクルード機能の説明をします。</p>
<div class="section" id="e3839ae383bce382b8e696ade78987e381aee382a4e383b3e382afe383abe383bce38389">
<h3><a name="e3839ae383bce382b8e696ade78987e381aee382a4e383b3e382afe383abe383bce38389">ページ断片のインクルード</a></h3>
<p>インクルードされるページ断片は、通常のページと同様に作成することができます。ただし、残念ながら現在のところ自動生成機構による作成支援はありませんので、手動でPageクラスとZPTテンプレートを用意する必要があります。</p>
<p>例えばヘッダとして/header.htmlというZPTテンプレートを作成し、次のようにinclude式を使ってページの中にヘッダを挿入することができます。</p>
<pre class="literal-block">
&lt;div tal:replace=&quot;structure include:/header.html&quot;&gt;BODY&lt;/div&gt;
</pre>
<p>include式のパラメータはインクルードするコンテンツのコンテキスト相対パスです。指定されたパスに対応するコンテンツのレンダリング結果がinclude式の評価結果となります。</p>
<p>デザインをWebブラウザで確認する都合上、header.htmlをHTML断片ではなく完全なHTML形式で書いておき、インクルードする時にはbodyタグの中身だけをインクルードしたいことがあります。その場合は次のようにinclude-body式を使うようにして下さい。</p>
<pre class="literal-block">
&lt;div tal:replace=&quot;structure include-body:/header.html&quot;&gt;BODY&lt;/div&gt;
</pre>
<div class="section" id="e383ace383b3e38380e383aae383b3e382b0e69982e381aee3808cselfe3808de381aee58685e5aeb9">
<h4><a name="e383ace383b3e38380e383aae383b3e382b0e69982e381aee3808cselfe3808de381aee58685e5aeb9">レンダリング時の「self」の内容</a></h4>
<p>ページ断片に関連づけられたPageオブジェクトが存在する場合、インクルードされたページ断片のレンダリング処理を行なう間だけ、そのPageオブジェクトがrequestスコープに「self」という名前でバインドされます（インクルードされたページ断片のレンダリングが終了した時点でselfの内容は元に戻されます）。</p>
<p>ページ断片に関連付けられたPageオブジェクトが存在しない場合はYmirは何の処理も行ないません。selfもインクルード元のPageオブジェクトがバインドされた状態のままになります。</p>
</div>
</div>
<div class="section" id="pagee382afe383a9e382b9e381aee3839ee38383e38394e383b3e382b0">
<h3><a name="pagee382afe383a9e382b9e381aee3839ee38383e38394e383b3e382b0">Pageクラスのマッピング</a></h3>
<p>ページ断片には通常のページと同様にPageオブジェクトを関連付けることができます。Pageオブジェクトを関連付けたい場合は、ページ断片のパスから規約に従って導き出されるクラス名でクラスを作成しておくだけで良いです。例えば/header.htmlというパスから導き出されるクラス名が<tt class="docutils literal"><span class="pre">com.example.web.HeaderPage</span></tt>だとすれば、このクラスを作成しておけばページ断片の処理時にこのクラスのオブジェクトが準備されて関連付けられます。</p>
<div class="section" id="pagee382aae38396e382b8e382a7e382afe38388e381aee6ba96e58299">
<h4><a name="pagee382aae38396e382b8e382a7e382afe38388e381aee6ba96e58299">Pageオブジェクトの準備</a></h4>
<p>JSFなどのフレームワークと違い、Ymirでは基本的にビュー部には関与せず、レンダリング処理はテンプレートエンジンに任せてしまうため、ページ内にどのページ断片がインクルードされているかをレンダリング前に知ることができません。</p>
<p>一方で、ページ内にインクルードされているページ断片に関連付けられているPageオブジェクトの準備は、主となるページに関連付けられているPageオブジェクトの準備と同じタイミングで一括して行なった方が都合が良いことが多いため、Ymirでは以下のようにアノテーションを使ってインクルード情報をPageクラスに指示するようにして、その情報を使ってレンダリング前に一括して全てのPageオブジェクトの準備を行なうようになっています。</p>
<pre class="literal-block">
@Include({ HeaderPage.class, FooterPage.class })
public class MainPage {
    ...
}
</pre>
<p>具体的には、主となるページに関連付けられているPageオブジェクトを準備するタイミングでアノテーションを辿ってPageオブジェクトツリーを内部に構築し、ツリーを深さ優先で辿っていって各Pageオブジェクトについてリクエストパラメータやオブジェクトスコープからのオブジェクトの設定などの準備処理を行なっていきます。上記の例ではMainPageが親でHeaderPageとFooterPageが子であるようなツリーが構築され、MainPage→HeaderPage→FooterPageの順に処理が行なわれます。</p>
<p>準備処理は、主となるPageオブジェクトを処理する際に一括して行なわれます。例えば上記の例では、次のように処理が行なわれます。</p>
<ol>
<li>...</li>
<li>MainPageへの@Inアノテーションの処理</li>
<li>HeaderPageへの@Inアノテーションの処理</li>
<li>FooterPageへの@Inアノテーションの処理</li>
<li>...</li>
<li>アクションメソッドの呼び出し（後述）</li>
<li>...</li>
<li>MainPage#_prerender()の呼び出し</li>
<li>HeaderPage#_prerender()の呼び出し</li>
<li>FooterPage#_prerender()の呼び出し</li>
<li>...</li>
</ol>
<p>インクルードされるPageオブジェクトには、主となるPageオブジェクトに設定されるものと同じリクエストパラメータやオブジェクトスコープのオブジェクトが設定されます。このためテンプレート中のインクルード指定で例えば以下のようにパスにリクエストパラメータを付与したとしても、インクルードされるPageコンポーネントにはそのパラメータは設定されません。</p>
<pre class="literal-block">
&lt;div tal:replace=&quot;structure include:/header.html?param=value&quot;&gt;BODY&lt;/div&gt;
</pre>
<p>なお、ページ内にインクルードするページ断片にPageクラスが関連付けられている場合は忘れずにアノテーションでページ断片のPageクラスを指示するようにして下さい。そうしないとPageオブジェクトの準備が行なわれません。</p>
</div>
<div class="section" id="e382a2e382afe382b7e383a7e383b3e383a1e382bde38383e38389e381aee591bce381b3e587bae38197">
<h4><a name="e382a2e382afe382b7e383a7e383b3e383a1e382bde38383e38389e381aee591bce381b3e587bae38197">アクションメソッドの呼び出し</a></h4>
<p>リクエストに対応するアクションメソッドの探索はPageオブジェクトツリーのそれぞれのPageオブジェクトについて深さ優先で行なわれ、一番最初に見つかったアクションメソッドが実行されます。</p>
<p>アクションメソッドの種類には、</p>
<ol>
<li>ボタンに対応するアクションメソッド（例：<tt class="docutils literal"><span class="pre">_post_search</span></tt>）</li>
<li>ボタンに対応するデフォルトアクションメソッド（例：<tt class="docutils literal"><span class="pre">_default_search</span></tt>）</li>
<li>通常のアクションメソッド（例：<tt class="docutils literal"><span class="pre">_post</span></tt>）</li>
<li>デフォルトアクションメソッド（例：<tt class="docutils literal"><span class="pre">_default</span></tt>）</li>
</ol>
<p>の4種類がありますが、探索はこれらの種類ごとに行なわれます。従って、例えば親Pageクラスに<tt class="docutils literal"><span class="pre">_post</span></tt>があり、子Pageクラスに<tt class="docutils literal"><span class="pre">_post_search</span></tt>がある場合は、子Pageクラスの<tt class="docutils literal"><span class="pre">_post_search</span></tt>が実行されることになります。</p>
<p>なお、<tt class="docutils literal"><span class="pre">_validationFailed</span></tt>メソッドや<tt class="docutils literal"><span class="pre">_permissionDenied</span></tt>メソッドの探索も同様に行なわれ、一番最初に見つかったメソッドが実行されます。</p>
<p><tt class="docutils literal"><span class="pre">_prerender</span></tt>メソッドは全てのPageオブジェクトについて呼び出されます。</p>
</div>
</div>
<div class="section" id="e6b3a8e6848fe4ba8be9a085">
<h3><a name="e6b3a8e6848fe4ba8be9a085">注意事項</a></h3>
<p>主となるページと同じディレクトリにページ断片を配置している場合、ページ断片を表すURLに直接アクセスされるとページ断片が表示されてしまいます。これを防ぐためには、org.seasar.ymir.impl.DeniedYmirPathMappingを使用します。</p>
<p>例えば「/included」ディレクトリ以下にページ断片を置く場合は、</p>
<pre class="literal-block">
&lt;component class=&quot;org.seasar.ymir.impl.DeniedYmirPathMapping&quot;&gt;
  &lt;arg&gt;&quot;/included/.*&quot;&lt;/arg&gt;
&lt;/component&gt;
</pre>
<p>のように指定することでページ断片への直接アクセスを禁止することができます。</p>
</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>
