Apache-tapestry-templates
Apacheタペストリー-テンプレート
このセクションのTapestry XMLテンプレートについて考えてみましょう。 XMLテンプレートは整形式のXMLドキュメントです。 ページのプレゼンテーション(ユーザーインターフェイス)レイヤーはXMLテンプレートです。 XMLテンプレートには、以下に示す項目に加えて、通常のHTMLマークアップがあります-
- タペストリー名前空間
- 拡張
- 要素
- コンポーネント
それらについて詳しく説明しましょう。
タペストリー名前空間
Tapestry名前空間は、XML名前空間に他なりません。 名前空間は、テンプレートのルート要素で定義する必要があります。 テンプレートにタペストリーコンポーネントとコンポーネント関連の情報を含めるために使用されます。 最も一般的に使用される名前空間は次のとおりです-
- xmlns:t =“ [[1]] — Tapestryの要素、コンポーネント、属性を識別するために使用されます。
- xmlns:p =“ tapestry:parameter” —コードの任意のチャンクをコンポーネントに渡すために使用されます。
タペストリー名前空間の例は次のとおりです-
<html xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:p = "tapestry:parameter">
<head>
<title>Hello World Page</title>
</head>
<body>
<h1>Hello World</h1>
<t:eventlink page = "Index">refresh page</t:eventlink>
</body>
</html>
拡張
拡張は、ページのレンダリング段階でXMLテンプレートを動的に変更するためのシンプルで効率的な方法です。 展開では、$ \ {<name>}構文を使用します。 XMLテンプレートで展開を表現する多くのオプションがあります。 最も一般的に使用されるオプションのいくつかを見てみましょう-
プロパティの拡張
対応するPageクラスで定義されたプロパティをマップします。 Javaクラスのプロパティ定義については、Java Bean仕様に準拠しています。 プロパティ名のケースを無視することで、さらに一歩進んでいます。 プロパティ展開を使用して「Hello World」の例を変更しましょう。 次のコードブロックは、変更されたPageクラスです。
package com.example.MyFirstApplication.pages;
public class HelloWorld {
//Java Bean Property
public String getName {
return "World!";
}
}
次に、対応するXMLテンプレートを次のように変更します。
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<title>Hello World Page</title>
</head>
<body>
<!-- expansion -->
<h1>Hello ${name}</h1>
</body>
</html>
ここでは、Pageクラスで name を Java Bean Property として定義し、拡張 $ \ {name} を使用してXMLテンプレートで動的に処理しました。
メッセージ拡張
各ページクラスには、リソースフォルダーに*«page_name».properties *というプロパティファイルが関連付けられている場合とない場合があります。 プロパティファイルは、1行に1つのキー/値のペア(メッセージ)を持つプレーンテキストファイルです。 HelloWorld Pageのプロパティファイルを次の場所に作成します。
「/src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties」に「Greeting」メッセージを追加します。
Greeting = Hello
*Greeting* メッセージは、XMLテンプレートで *$ \ {message:greeting}* として使用できます。
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<title>Hello World Page</title>
</head>
<body>
<!-- expansion -->
<h1>${message:greeting} ${name}</h1>
</body>
</html>
要素
Tapestryには、XMLテンプレートで使用される要素の小さなセットがあります。 要素はTapestry名前空間の下で定義された事前定義されたタグです-
https://tapestry.apache.org/schema/tapestry_5_4.xsd
各要素は特定の目的のために作成されます。 利用可能なタペストリーの要素は次のとおりです-
<t:body>
2つのコンポーネントがネストされている場合、親コンポーネントのテンプレートは子コンポーネントのテンプレートをラップする必要があります。 <t:body>要素は、この状況で役立ちます。 <t:body>の用途の1つは、テンプレートレイアウトです。
一般に、Webアプリケーションのユーザーインターフェイスには、共通ヘッダー、フッター、メニューなどがあります。 これらの共通項目はXMLテンプレートで定義され、テンプレートレイアウトまたはレイアウトコンポーネントと呼ばれます。 Tapestryでは、アプリケーション開発者が作成する必要があります。 レイアウトコンポーネントは別のコンポーネントであり、 src/main/«java | resources»/«package_name»/components というパスを持つコンポーネントフォルダの下に配置されます。
*MyCustomLayout* という単純なレイアウトコンポーネントを作成しましょう。 MyCustomLayoutのコードは次のとおりです-
<!DOCTYPE html>
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<meta charset = "UTF-8"/>
<title>${title}</title>
</head>
<body>
<div>Sample Web Application</div>
<h1>${title}</h1>
<t:body/>
<div>(C) 2016 finddevguides.</div>
</body>
</html>
package com.example.MyFirstApplication.components;
import org.apache.tapestry5.*;
import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.BindingConstants;
public class MyCustomLayout {
@Property
@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
private String title;
}
MyCustomLayoutコンポーネントクラスでは、タイトルフィールドを宣言し、アノテーションを使用して必須フィールドにしました。 次に、HelloWorldlテンプレートを変更して、以下のコードブロックに示すようにカスタムレイアウトを使用します。
<html>
t:type = "mycustomlayout" title = "Hello World Test page"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<h1>${message:greeting} ${name}</h1>
</html>
ここでは、XMLテンプレートにheadタグとbodyタグがないことがわかります。 Tapestryはこれらの詳細をレイアウトコンポーネントから収集し、レイアウトコンポーネントの<t:body>はHelloWorldテンプレートに置き換えられます。 すべてが完了すると、Tapestryは以下に指定されているのと同様のマークアップを出力します-
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8"/>
<title>Hello World Test Page</title>
</head>
<body>
<div>Sample Web Application</div>
<h1>Hello World Test Page</h1>
<h1>Hello World!</h1>
<div>(C) 2016 finddevguides.</div>
</body>
</html>
レイアウトはネストできます。 たとえば、管理機能を含めることでカスタムレイアウトを拡張し、以下で指定するように管理セクションで使用できます。
<html t:type = "MyCommonLayout"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<div><!-- Admin related items --><div>
<t:body/>
</html>
<t:container>
<t:container>はトップレベルの要素であり、タペストリー名前空間が含まれています。 これは、コンポーネントの動的セクションを指定するために使用されます。
たとえば、グリッドコンポーネントには、HTMLテーブル内で行(tr(および列td))をレンダリングする方法を識別するテンプレートが必要な場合があります。
<t:container xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<td>${name}</td>
<td>${age}</td>
</t:container>
<t:block>
<t:block>は、テンプレート内の動的セクションのプレースホルダーです。 通常、ブロック要素はレンダリングされません。 のみ、テンプレートで定義されたコンポーネントはブロック要素を使用します。 コンポーネントはデータをブロック要素に動的に注入し、レンダリングします。 一般的な使用例の1つは AJAX です。
ブロック要素は、レンダリングされる動的データの正確な位置とマークアップを提供します。 すべてのブロック要素には、対応するJavaプロパティが必要です。 その後のみ、動的にレンダリングできます。 ブロック要素のidは、Java変数識別子規則に従う必要があります。 部分的なサンプルを以下に示します。
@Inject
private Block block;
<html t:type = "mycustomlayout" title = "block example"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<h1>${title}</h1>
<!--
...
...
-->
<t:block t:id = "block">
<h2>Highly dynamic section</h2>
I'v been updated through AJAX call
The current time is: <strong>${currentTime}</strong>
</t:block>
<!--
...
...
-->
</html>
<t:content>
<t:content>要素は、テンプレートの実際のコンテンツを指定するために使用されます。 一般に、すべてのマークアップはテンプレートの一部と見なされます。 <t:content>が指定されている場合、その中のマークアップのみが考慮されます。 この機能は、レイアウトコンポーネントなしでページを設計するためにデザイナーによって使用されます。
<t:remove>
<t:remove>は、コンテンツ要素の反対です。 remove要素内のマークアップは、テンプレートの一部とは見なされません。 サーバーのみのコメントおよび設計目的に使用できます。
資産
アセットは、スタイルシート、画像、JavaScriptファイルなどの静的リソースファイルです。 通常、アセットはWebアプリケーションのルートディレクトリ /src/main/webapp に配置されます。
<head>
<link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>
Tapestryは、* Javaクラスパス*に保存されているファイルもアセットとして扱います。 Tapestryには、拡張オプションを使用してアセットをテンプレートに含めるための高度なオプションが用意されています。
- コンテキスト-Webコンテキストで利用可能なアセットを取得するオプション。
<img src = "${context:image/tapestry_banner.gif}" alt = "Banner"/>
*asset* -コンポーネントは通常、Javaクラスとともにjarファイル内に独自のアセットを保存します。 Tapestry 5.4以降、クラスパスにアセットを保存する標準パスは *META-INF/assets* です。 ライブラリの場合、アセットを保存する標準パスは* META-INF/assets/«library_name»/です。 asset:*は、* context:*拡張を呼び出して、Webコンテキストからアセットを取得することもできます。
<img src = "${asset:context:image/tapestry_banner.gif}" alt = "Banner"/>
アセットは、InjectおよびPathアノテーションを使用してTapestryページまたはコンポーネントに挿入できます。 Pathアノテーションのパラメーターは、アセットの相対パスです。
@Inject
@Path("images/edit.png")
private Asset icon;
- Pathパラメーター*には、 AppModule.java セクションで定義されたTapestryシンボルを含めることもできます。
たとえば、値context:skins/basicを使用してシンボルskin.rootを定義し、以下に示すように使用できます-
@Inject
@Path("${skin.root}/style.css")
private Asset style;
ローカライゼーション
タペストリーを介してリソースを含めると、追加機能が提供されます。 そのような機能の1つが「ローカリゼーション」です。 Tapestryは現在のロケールをチェックし、適切なリソースを含めます。
たとえば、現在のロケールが de に設定されている場合、edit.pngの代わりに edit_de.png が含まれます。
CSS
Tapestryには組み込みのスタイルシートのサポートがあります。 Tapestryは、 tapestry.css をコアJavaScriptスタックの一部として挿入します。 Tapestry 5.4以降、tapestryには bootstrap css framework も含まれています。 通常のリンクタグを使用して、独自のスタイルシートを含めることができます。 この場合、スタイルシートはWebルートディレクトリ( /src/main/webapp/ )にある必要があります。
<head>
<link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>
先に説明したように、Tapestryには拡張オプションによりスタイルシートをテンプレートに含めるための高度なオプションが用意されています。
<head>
<link href = "${context:css/site.css}" rel = "stylesheet" type = "text/css"/>
Tapestryは、スタイルシートをJavaクラスに直接含めるためのインポートアノテーションも提供します。
@Import(stylesheet="context:css/site.css")
public class MyCommonLayout {
}
Tapestryには、AppModule.javaを介してスタイルシートを管理するための多くのオプションが用意されています。 重要なオプションのいくつかは次のとおりです-
- タペストリーのデフォルトのスタイルシートは削除できます。
@Contribute(MarkupRenderer.class)
public static void
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) {
configuration.override("InjectDefaultStyleheet", null);
}
- ブートストラップは、パスをオーバーライドすることで無効にすることもできます。
configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
*アセット(CSSおよびJavaScript)の動的な最小化を有効にします。* tapestry-webresources *依存関係(pom.xml内)も含める必要があります。
@Contribute(SymbolProvider.class)
@ApplicationDefaults
public static void contributeApplicationDefaults(
MappedConfiguration<String, String> configuration) {
configuration.add(SymbolConstants.MINIFICATION_ENABLED, "true");
}
<dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-webresources</artifactId>
<version>5.4</version>
</dependency>
クライアント側のJavaScript
現在の世代のWebアプリケーションは、豊富なクライアントサイドエクスペリエンスを提供するためにJavaScriptに大きく依存しています。 Tapestryはそれを認め、JavaScriptのファーストクラスのサポートを提供します。 JavaScriptのサポートはタペストリーに深く根付いており、プログラミングのあらゆる段階で利用できます。
以前、TapestryはPrototypeとScriptaculousのみをサポートしていました。 しかし、バージョン5.4から、タペストリーはJavaScriptレイヤーを完全に書き直して、可能な限り汎用的にし、JavaScriptのデファクトライブラリであるJQueryのファーストクラスサポートを提供しています。 また、タペストリーはモジュールベースのJavaScriptプログラミングを推奨し、AMDの一般的なクライアント側実装であるRequireJSをサポートします(非同期モジュール定義-モジュールとその依存関係を非同期でサポートするJavaScript仕様)。
ロケーション
JavaScriptファイルはTapestryアプリケーションのアセットです。 アセットルールに従って、JavaScriptファイルはWebコンテキスト /sr/main/webapp/ の下に配置されるか、jar内の META-INF/assets/location の下に配置されます。
JavaScriptファイルのリンク
XMLテンプレートでJavaScriptファイルをリンクする最も簡単な方法は、scriptタグを直接使用することです。これは、 <script language = "javascript" src = "relative/path/to/js"> </script> です。 しかし、タペストリーはこれらのアプローチを推奨していません。 Tapestryには、ページ/コンポーネント自体でJavaScriptファイルをリンクするためのオプションがいくつか用意されています。 これらのいくつかを以下に示します。
- * @ importアノテーション*-@importアノテーションは、コンテキスト式を使用して複数のJavaScriptライブラリをリンクするオプションを提供します。 Pageクラスとそのメソッドの両方に適用できます。 Pageクラスに適用される場合、すべてのメソッドに適用されます。 ページのメソッドに適用された場合、そのメソッドにのみ適用され、メソッドが呼び出されたときにのみTapestryはJavaScriptライブラリをリンクします。
@Import(library = {"context:js/jquery.js","context:js/myeffects.js"})
public class MyComponent {
//...
}
- * JavaScriptSupportインターフェイス*-JavaScriptSupportはタペストリーで定義されたインターフェイスで、JavaScriptファイルをインポートする importJavaScriptLibrary メソッドがあります。 JavScriptSupportオブジェクトは、@ Environmental注釈を宣言して注釈を付けるだけで簡単に作成できます。
@Inject @Path("context:/js/myeffects.js")
private Asset myEffects;
@Environmental
private JavaScriptSupport javaScriptSupport;
void setupRender() {
javaScriptSupport.importJavaScriptLibrary(myEffects);
}
- JavaScripSupportは、 @ Environmental アノテーションを使用してのみコンポーネントに注入できます。 サービスについては、 @ Inject アノテーションを使用するか、サービスコンストラクターメソッドの引数として追加する必要があります。
@Inject
private JavaScriptSupport javaScriptSupport;
public MyServiceImpl(JavaScriptSupport support) {
//...
}
- * addScriptメソッド*-これはJavaScriptSupportインターフェイスに似ていますが、 addScript メソッドを使用し、ページの下部の出力にコードが直接追加される点が異なります。
void afterRender() {
javaScriptSupport.addScript(
"$('%s').observe('click', hideMe());", container.getClientId());
}
JavaScriptスタック
Tapestryでは、JavaScriptファイルのグループと関連するスタイルシートを組み合わせて、1つのエンティティとして使用できます。 現在、TapestryにはPrototypeベースおよびJQueryベースのスタックが含まれています。
開発者は、 JavaScriptStack インターフェイスを実装して独自のスタックを開発し、 AppModule.java に登録できます。 登録したら、 @ import アノテーションを使用してスタックをインポートできます。
@Contribute(JavaScriptStackSource.class)
public static void addMyStack(
MappedConfiguration<String, JavaScriptStack> configuration) {
configuration.addInstance("MyStack", myStack.class);
}
@Import(stack = "MyStack")
public class myPage {
}