Apache Tapestry 模板


让我们考虑本节中的 Tapestry XML 模板。 XML 模板是格式良好的 XML 文档。页面的表示(用户界面)层是 XML 模板。一个 XML 模板除了下面给出的项目之外还有正常的 HTML 标记:

  • 挂毯命名空间
  • 扩展
  • Elements
  • 成分

现在让我们详细讨论它们。

挂毯命名空间


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 模板的简单有效的方法。扩展使用 ${} 语法。在 XML 模板中有很多选项可以表达扩展。让我们看看一些最常用的选项:

属性扩展

它映射相应 Page 类中定义的属性。它遵循 Java 类中属性定义的 Java Bean 规范。它通过忽略属性名称的情况更进一步。让我们使用属性扩展来更改“Hello World”示例。以下代码块是修改后的 Page 类。

package com.example.MyFirstApplication.pages; 
public class HelloWorld {   
    // Java Bean 属性
    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 as Java Bean 属性 在 Page 类中并使用扩展在 XML 模板中对其进行动态处理 ${name} .

消息扩展

每个页面类可能有也可能没有关联的属性文件—— «page_name».properties 在资源文件夹中。属性文件是纯文本文件,每行有一个键/值对(消息)。让我们在以下位置为 HelloWorld 页面创建一个属性文件:

“/src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties”并添加“问候”消息。

Greeting = Hello

The Greeting 消息可以在 XML 模板中用作 ${消息:问候}

<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>

Elements


Tapestry 有一小部分要在 XML 模板中使用的元素。元素是在 Tapestry 命名空间下定义的预定义标签:

https://tapestry.apache.org/schema/tapestry_5_4.xsd

每个元素都是为特定目的而创建的。可用的挂毯元素如下:

当两个组件嵌套时,父组件的模板可能不得不包裹子组件的模板。 元素在这种情况下很有用。 的用途之一是在模板布局中。

一般来说,Web 应用程序的用户界面会有一个公共的页眉、页脚、菜单等。这些公共项目在 XML 模板中定义,称为模板布局或布局组件。在 Tapestry 中,它需要由应用程序开发人员创建。布局组件只是另一个组件,位于 components 文件夹下,该文件夹具有以下路径 - src/main/«java|resources»/«package_name»/components .

让我们创建一个简单的布局组件,称为 我的自定义布局 . 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 NewbieGo.</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 组件类中,我们声明了一个标题字段,并且通过使用注释,我们将其设为强制性。现在,更改 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 将从布局组件中收集这些细节,并且布局组件的 将被 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 NewbieGo.</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>

是一个顶级元素,包括一个挂毯命名空间。这用于指定组件的动态部分。

例如,一个网格组件可能需要一个模板来确定如何在 HTML 表格中呈现其行 - tr(和列 td)。

<t:container xmlns:t = "http:// Tapestry.apache.org/schema/tapestry_5_4.xsd">
    <td>${name}</td>
    <td>${age}</td>
</t:container>

是模板中动态部分的占位符。通常,块元素不渲染。只有模板中定义的组件使用块元素。组件会将数据动态地注入块元素并渲染它。一种流行的用例是 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>

元素用于指定模板的实际内容。通常,所有标记都被视为模板的一部分。如果指定了 ,则只考虑其中的标记。设计人员使用此功能来设计没有布局组件的页面。

与内容元素正好相反。移除元素内的标记不被视为模板的一部分。它可用于仅服务器评论和设计目的。

Assets


资产是静态资源文件,例如样式表、图像和 JavaScript 文件。通常,assets 放在 web 应用程序根目录下 /src/main/webapp .

<head> 
    <link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>

Tapestry 还处理存储在 Java 类路径 作为资产。 Tapestry 提供高级选项以通过扩展选项将资产包含到模板中。

  • Context : 获取网络环境中可用资产的选项。

<img src = "${context:image/tapestry_banner.gif}" alt = "Banner"/>

asset : 组件通常将自己的资产与 Java 类一起存储在 jar 文件中。从 Tapestry 5.4 开始,在类路径中存储资产的标准路径是 META-INF/资产 .对于库,存储资产的标准路径是 META-INF/assets/«library_name»/。资产: 也可以打电话 context: 扩展以从 Web 上下文中获取资产。

<img src = "${asset:context:image/tapestry_banner.gif}" alt = "Banner"/>

可以使用 Inject 和 Path 注释将资产注入 Tapestry 页面或组件。 Path 注释的参数是资产的相对路径。

@Inject 
@Path("images/edit.png") 
private Asset icon;

The 路径参数 还可以包含在 应用模块.java section.

例如,我们可以定义一个符号 skin.root,其值为 context:skins/basic 并使用它,如下所示:

@Inject 
@Path("${skin.root}/style.css") 
private Asset style;

本土化

通过挂毯包含资源提供了额外的功能。其中一项功能是“本地化”。 Tapestry 将检查当前语言环境并包含适当的资源。

例如,如果当前语言环境设置为 de , then edit_de.png 将被包含而不是 edit.png。

CSS


Tapestry 具有内置的样式表支持。 Tapestry 将注入 挂毯.css 作为核心 Javascript 堆栈的一部分。从 Tapestry 5.4 开始,tapestry 包括 引导 css 框架 也是。我们可以使用普通的链接标签包含我们自己的样式表。在这种情况下,样式表应该在 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)的动态最小化。我们需要包括 挂毯网络资源 依赖项(在 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 版开始,tapestry 完全重写了 JavaScript 层,使其尽可能通用,并为 JQuery(事实上的 JavaScript 库)提供一流的支持。此外,tapestry 鼓励基于模块的 JavaScript 编程并支持 RequireJS,这是一种流行的 AMD 客户端实现(异步模块定义 - JavaScript 规范,以异步方式支持模块及其依赖项)。

Location

JavaScript 文件是 Tapestry 应用程序的资产。根据资产规则,JavaScript 文件要么放在 web 上下文中,要么放在 /sr/main/webapp/ 或放在罐子下 META-INF/资产/位置 .

链接 JavaScript 文件


在 XML Template 中链接 JavaScript 文件最简单的方法是直接使用 script 标签,即: .但是,tapestry 不推荐这些方法。 Tapestry 提供了几个选项来链接页面/组件本身中的 JavaScript 文件。其中一些在下面给出。

  • @import 注解 : @import 注解提供了使用上下文表达式链接多个 JavaScript 库的选项。它可以应用于 Page 类及其方法。如果应用于 Page 类,则它适用于其所有方法。如果应用于页面的方法,它只应用于该方法,然后 Tapestry 仅在调用该方法时链接 JavaScript 库。

@Import(library = {"context:js/jquery.js","context:js/myeffects.js"}) 

public class MyComponent { 
    // ...
}
  • JavaScript支持接口 : JavaScriptSupport是tapestry定义的一个接口,它有一个方法, 导入JavaScript库 导入 JavaScript 文件。 JavScriptSupport 对象可以通过简单地声明和使用@Environmental 注释来轻松创建。

@Inject @Path("context:/js/myeffects.js") 
private Asset myEffects;  

@Environmental 
private JavaScriptSupport javaScriptSupport;  
void setupRender() { 
    javaScriptSupport.importJavaScriptLibrary(myEffects);
}
  • JavaScripSupport 只能使用 @环境的 注解。对于服务,我们需要使用 @Inject 注释或将其作为参数添加到服务构造方法中。

@Inject 
private JavaScriptSupport javaScriptSupport; 
public MyServiceImpl(JavaScriptSupport support) { 
    // ...
}
  • addScript 方法 : 这个类似于 JavaScriptSupport 接口,只是它使用了 添加脚本 方法和代码直接添加到页面底部的输出中。

void afterRender() { 
    javaScriptSupport.addScript(
        "$('%s').observe('click', hideMe());", container.getClientId());
}

JavaScript 堆栈


Tapestry 允许将一组 JavaScript 文件和相关的样式表组合起来并作为一个单独的实体使用。目前,Tapestry 包括基于原型和基于 JQuery 的堆栈。

开发人员可以通过实现 JavaScript堆栈 interface and register it in the 应用模块.java .注册后,可以使用以下命令导入堆栈 @import 注解。

@Contribute(JavaScriptStackSource.class) 
public static void addMyStack(
    MappedConfiguration<String, JavaScriptStack> configuration) {
   
    configuration.addInstance("MyStack", myStack.class);
}  

@Import(stack = "MyStack") 
public class myPage { 
}