Layoutコンポーネントという記述をしばしば見かけることでしょう。 しかし、それをコンポーネントリファレンス内に見つけることはできません。 Layoutはコンポーネントではなく、コンポーネントの パータン なのです。
Layoutコンポーネントは、アプリケーション内の全てのページに渡って共通なコンテンツを提供するためのものです。 サーブレットでの伝統的な開発では、JSPインクルードを使ってページのトップにバナーを、下部にコピーライトの文言を挿入するということがよく行われています。
Tapestryにはそのようなインクルードの仕組みはありません。必要がないのです。
そのかわり、ページのひな形として振る舞うコンポーネントを作ることができます。
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> <head> <title>My Nifty Web Application</title> </head> <body> <div class="nav-top"> Nifty Web Application </div> <t:body/> <div class="nav-bottom"> (C) 2008 NiftyWebCo, Inc. </div> </body> </html>
Layoutは、普通のコンポーネントテンプレートを持った普通のコンポーネントです。 他のコンポーネントテンプレートと同じくクラスパス内に(すなわち、src/main/resources に)配置します。
ポイントとなるのは、中央にある <t:body/> 要素です; これは ページのコンテンツ に置き換えられます。
この例では <t:body> の上下にふたつの <div> 要素があります。 そこが、バナー(そしてバナー広告!)やメニュー、ログインフォームなどのWebアプリケーション内に現れる典型的なコンテンツのプレースホルダとなります。
しばしばこれらはとても複雑になります ... 実際、多くのアプリケーションにおいて、ほとんどどのページよりもLayoutコンポーネントの方が大きくなるでしょう。
画像やスタイルシートなどのリソースへのリンクを張る場合、絶対URLを使わなければならないことを覚えていてください。 同じコンポーネントが異なるフォルダ内のページで使用され、あるいは異なる数のアクティベーションコンテキストとともに使用されるので、 相対URLはページ毎に異なるものになるだけでなく不意に変化してしまうかもしれません。
@IncludeStylesheet("context:css/site.css") public class Layout { }
コンポーネントは必ずJavaクラスを伴っていなければなりません。この簡単な例では、Layoutコンポーネントはほとんどロジックを持っていません。 (テンプレートに <link> 要素を直接記述するかわりに) @IncludeStylesheet アノテーションを用いて、タイプ量をいくらか減らすことができます。
<html t:type="layout" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> <h1>Welcome to the Nifty Web Application!</h1> <p> Would you like to <t:pagelink page="login">Log In</t:pagelink>? </p> </html>
これはLayoutコンポーネントを使用した例です。Start.tmlテンプレートをプレビュー可能なものにしておくために <html> 要素を使用し、 そこに t:type アトリビュートでコンポーネントの指定をしています。
<html> タグは取り除かれ、(<html> 要素で始まっている)Layout.tmlテンプレートの内容に置き換えられます。 Layout.tml内の <t:body> はページの内容に置き換えられます。この例では <h1> タグと <p> タグです。
このパターンを使用しているアプリケーション内のページは、Layoutコンポーネントを使用することでどのページも同じ外観を持つことになります。
アプリケーション内に複数の外観が必要になることもあるでしょう: ユーザー登録ページがある外観を持ち管理画面には別の外観を持たせる、というように。 これは、複数のLayoutコンポーネントを作成し、ページ毎に異なるLayoutを使用することで実現できます。