- Apache Tapestry 教程
- Apache Tapestry - 首頁
- Apache Tapestry - 概述
- Apache Tapestry - 架構
- Apache Tapestry - 安裝
- Apache Tapestry - 快速入門
- Apache Tapestry - 專案佈局
- 約定優於配置
- Apache Tapestry - 註解
- 頁面和元件
- Apache Tapestry - 模板
- Apache Tapestry - 元件
- 內建元件
- 表單和驗證元件
- Apache Tapestry - Ajax 元件
- Apache Tapestry - Hibernate
- Apache Tapestry - 儲存
- 高階功能
- Apache Tapestry 有用資源
- Apache Tapestry - 快速指南
- Apache Tapestry - 有用資源
- Apache Tapestry - 討論
Apache Tapestry - 模板
在本節中,讓我們考慮 Tapestry XML 模板。XML 模板是一個格式良好的 XML 文件。頁面的表示(使用者介面)層是 XML 模板。XML 模板除了以下專案外,還包含普通的 HTML 標記 -
- Tapestry 名稱空間
- 擴充套件
- 元素
- 元件
現在讓我們詳細討論它們。
Tapestry 名稱空間
Tapestry 名稱空間只不過是 XML 名稱空間。名稱空間應在模板的根元素中定義。它用於在模板中包含 Tapestry 元件和與元件相關的資訊。最常用的名稱空間如下 -
xmlns:t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” — 用於識別 Tapestry 的元素、元件和屬性。
xmlns:p = “tapestry:parameter” — 用於將任意程式碼塊傳遞給元件。
Tapestry 名稱空間示例如下 -
<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 模板中表達擴充套件有很多選項。讓我們看看一些最常用的選項 -
屬性擴充套件
它對映在相應頁面類中定義的屬性。它遵循 Java Bean 規範來定義 Java 類中的屬性。它更進一步,忽略屬性名稱的大小寫。讓我們使用屬性擴充套件更改“Hello World”示例。以下程式碼塊是修改後的頁面類。
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>
在這裡,我們在頁面類中將 name 定義為 Java Bean 屬性,並在 XML 模板中使用擴充套件 ${name} 動態處理它。
訊息擴充套件
每個頁面類可能有也可能沒有關聯的屬性檔案 - 資原始檔夾中的 «page_name».properties。屬性檔案是純文字檔案,每行包含一個鍵/值對(訊息)。讓我們為 HelloWorld 頁面建立一個屬性檔案,位於 -
“/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
每個元素都是為了特定目的而建立的。可用的 Tapestry 元素如下 -
<t:body>
當兩個元件巢狀時,父元件的模板可能需要包裝子元件的模板。<t:body> 元素在這種情況下很有用。<t:body> 的用途之一是在模板佈局中。
通常,Web 應用程式的使用者介面將具有公共的頁首、頁尾、選單等。這些公共專案在 XML 模板中定義,稱為模板佈局或佈局元件。在 Tapestry 中,它需要由應用程式開發人員建立。佈局元件只是另一個元件,放置在 components 資料夾下,其路徑如下 - 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 TutorialsPoint.</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 元件類中,我們聲明瞭一個 title 欄位,並透過使用註解,使其成為強制性的。現在,更改 HelloWorld.html 模板以使用我們的自定義佈局,如下面的程式碼塊所示。
<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 TutorialsPoint.</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> 是頂級元素,包含 Tapestry 名稱空間。這用於指定元件的動態部分。
例如,網格元件可能需要一個模板來識別如何在 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> 是模板中動態部分的佔位符。通常,block 元素不渲染。只有在模板中定義的元件使用 block 元素。元件將動態地將資料注入到 block 元素中並渲染它。其中一個流行的用例是 AJAX。
block 元素為要渲染的動態資料提供確切的位置和標記。每個 block 元素都應該有一個對應的 Java 屬性。只有這樣才能動態渲染它。block 元素的 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> 只是 content 元素的反面。remove 元素內的標記不被視為模板的一部分。它可以用於伺服器端註釋和設計目的。
資產
資產是靜態資原始檔,例如樣式表、影像和 JavaScript 檔案。通常,資產放置在 Web 應用程式根目錄 /src/main/webapp 中。
<head> <link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>
Tapestry 也將儲存在 Java 類路徑 中的檔案視為資產。Tapestry 提供高階選項,可以透過擴充套件選項將資產包含到模板中。
Context - 獲取 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 符號。
例如,我們可以定義一個符號 skin.root,其值為 context:skins/basic,並按如下所示使用它 -
@Inject
@Path("${skin.root}/style.css")
private Asset style;
本地化
透過 Tapestry 包含資源提供了額外的功能。其中一項功能是“本地化”。Tapestry 將檢查當前區域設定幷包含正確的資源。
例如,如果當前區域設定設定為 de,則將包含 edit_de.png 而不是 edit.png。
CSS
Tapestry 具有內建的樣式表支援。Tapestry 將 tapestry.css 作為核心 Javascript 堆疊的一部分注入。從 Tapestry 5.4 開始,Tapestry 也包含 bootstrap css 框架。我們可以使用普通的 link 標籤包含我們自己的樣式表。在這種情況下,樣式表應該位於 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 還提供 Import 註解,可以直接將樣式表包含到 Java 類中。
@Import(stylesheet="context:css/site.css")
public class MyCommonLayout {
}
Tapestry 提供了許多透過 AppModule.java 管理樣式表的選項。一些重要的選項是 -
可以刪除 Tapestry 預設樣式表。
@Contribute(MarkupRenderer.class)
public static void
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) {
configuration.override("InjectDefaultStyleheet", null);
}
也可以透過覆蓋其路徑來停用 Bootstrap。
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,並在程式設計的每個階段都可用。
早些時候,Tapestry 僅支援 Prototype 和 Scriptaculous。但是,從 5.4 版本開始,Tapestry 完全重寫了 JavaScript 層,使其儘可能通用,併為 JQuery(JavaScript 事實上的庫)提供一流的支援。此外,Tapestry 鼓勵基於模組的 JavaScript 程式設計,並支援 RequireJS,這是 AMD(非同步模組定義 - JavaScript 規範,用於以非同步方式支援模組及其依賴項)的流行客戶端實現。
位置
JavaScript 檔案是 Tapestry 應用程式的資產。根據資產規則,JavaScript 檔案要麼放置在 Web 上下文中 /sr/main/webapp/,要麼放置在 jar 中的 META-INF/assets/ 位置。
連結 JavaScript 檔案
在 XML 模板中連結 JavaScript 檔案最簡單的方法是直接使用 script 標籤,即 − <script language = "javascript" src = "relative/path/to/js"></script>。但是,Tapestry 不推薦這種方法。Tapestry 提供了幾種選項,可以在頁面/元件本身中直接連結 JavaScript 檔案。以下是一些示例。
@import 註解 − @import 註解提供了使用上下文表達式連結多個 JavaScript 庫的選項。它可以應用於頁面類及其方法。如果應用於頁面類,則它適用於該類中的所有方法。如果應用於頁面的方法,則它僅適用於該方法,然後 Tapestry 僅在呼叫該方法時連結 JavaScript 庫。
@Import(library = {"context:js/jquery.js","context:js/myeffects.js"})
public class MyComponent {
// ...
}
JavaScriptSupport 介面 − JavaScriptSupport 是 Tapestry 定義的一個介面,它有一個方法 importJavaScriptLibrary 用於匯入 JavaScript 檔案。可以透過簡單地宣告並使用 @Environmental 註解進行註釋來輕鬆建立 JavaScriptSupport 物件。
@Inject @Path("context:/js/myeffects.js")
private Asset myEffects;
@Environmental
private JavaScriptSupport javaScriptSupport;
void setupRender() {
javaScriptSupport.importJavaScriptLibrary(myEffects);
}
JavaScriptSupport 只能使用 @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 檔案和相關的樣式表組合並用作一個實體。目前,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 {
}