Tapestry 5 组件模板
本文根据http://tapestry.apache.org/tapestry5/tapestry-core/guide/templates.html翻译整理过来,请高手指正,转载请注明出处!
Tapestry中,组件模板是与页面或组件类相关的文件,包含组件以及其内嵌组件的标记(markup)。
从Tapestry 4中变化而来,在Tapestry 5中,组件模板是格式良好的XML文档。这意味着每一个起始标签必须有一个相匹配的结束标签,每一个属性都要被引用起来等等。
模板多半是标准的(X)HTML;Tapestry以提供Tapestry命名空间的形式扩展了普通的标记(markup)。
我们将简短介绍模板的具体内容,首先详细介绍组件与模板是如何联系的。
模板定位
组件模板与组件类文件存放在一起,文件后缀名为".html",与相应组件类存放在同一包下。
在典型的Maven目录结构中,组件的Java类可以是src/main/java/org/example/myapp/components/MyComponent.java。相应的模板将会是src/main/resources/org/example/myapp/components/MyComponent.html。
与此同时,页面的Java类可以是src/main/java/org/example/myapp/pages/MyPage.java。相应的模板将会是src/main/resources/org/example/myapp/pages/MyPage.html。
模板与被编译的类将会被一起打包到WAR应用包的WEB-INF/classes文件夹下。
对于页面(非组件),还有一个位置将会被查找:web应用目录下(web application context),位置是基于页面的逻辑名,在先前的一个例子中,模板应该是在web应用根目录下的MyPage.html。
类路径下的模板要优先于web应用目录下的模板文件。
模板国际化
模板像单独的组件信息分类文件一样被国际化(localized)了:文件名后接有效的local(如en,zh_CN)。因此德国的用户将看到由MyPage_de.html生成的页面内容,法国的用户将看到由MyPage_fr.html生成的页面内容,当没有明确的国际化文件时,默认的国际化文件(MyPage.html)会被使用。
模板继承
 
如果一个组件没有模板,但是它继承的父组件类有模板,此时父类的模板将会被用作子模板。
这就允许组件继承基类的模板而不是重复基类的模板。
Tapestry命名空间
 
组件模板应该包括Tapestry命名空间,其定义在模板的根元素中。
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<head>
<title>Hello World Page</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
这里的命名空间定义使用了标准的前缀“t:”,这一页中的实例都采用这一标准前缀。
Tapestry元素
Tapestry元素都采用Tapestry命名空间前缀定义的元素。
其他元素应该在默认的命名空间中,没有前缀。
 
<body
 
在许多情况下,组件被设计成与其模板中内嵌的模板整合在一起。
<body>元素被用来标识组件模板中的内嵌模板的body被呈现(rendered)在哪里。
组件可以控制(经常)其body是否被呈现。
以下实例是一个Layout组件,页面具体内容里面添加了基本的HTML元素。
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<head>
<title>My Tapestry Application</title>
</head>
<body>
<t:body/>
</body>
</html>
以下是页面应该如何使用这一组件:
<t:layout xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
My Page Specific Content
</t:layout>
当页面呈现时,页面模板和其外围的组件模板被合并到了一起:
<html>
<head>
<title>My Tapestry Application</title>
</head>
<body>
My Page Specific Content
</body>
</html>
Tapestry 4用户将意识到<body>元素就是RenderBody 组件的替代。
<block
block是组件部分模板的容器。block不会正常呈现(render),任何组件或内容放入一个block都不会被正常呈现。然而,通过注入block,你可以精确控制什么时候及是否呈现内容。
block可以是匿名的,或者拥有一个id(通过id属性来指定)。非匿名block可以注入(injected)到组件里。
<parameter
参数元素是一个特殊类型的block,它被放置在一个内嵌组件的body中。block通过<parameter>定义传入到组件。<parameter>包含一个必须的name属性用以识别绑定了组件的哪一个参数。
Example:
<t:if test="loggedIn">
Hello, ${userName}!
<t:parameter name="else">
Click <a t:type="actionlink" t:id="login">here</a> to log in.
</t:parameter>
</t:if>
扩展表达式(Expansions
另外一种呈现输出就是使用扩展表达式。扩展表达式是可以内嵌在模板体内的特殊字符串,借用了Ant构建工具的一些语法。
Welcome, ${userId}!
在此,${userId}是一个扩展表达式。此例中,组件的属性userId被提取出来转换成一个字符串流向输出。
扩展表达式只能用在普通的模板文本中;不允许用在属性中或者CDATA段中。
从其特性来讲,扩展表达式和参数绑定(parameter bindings)一样,它的默认绑定前缀为"prop:"(表示一个属性名),还有其他的绑定前缀也很有用,特别是"message:"(用来访问组件分类信息中的国际化信息)。
Tapestry 4用户会注意到扩展表达式很简洁,它轻松替代了Insert组件或者<span key="...">标识。
组件元素
 
一个内嵌的组件在模板中被识别为t:命名空间下的元素。如:
You have ${cartItems.size()} items in your cart.
<t:actionlink t:id="clear">Remove All</t:actionlink>.
元素名"actionlink"用于标识组件的类型——"ActionLink"(Tapesty在识别组件类型时不区分大小写)。
内嵌组件可以有两个Tapestry相关的参数:
§                 id:组件的唯一id(在其容器中)。
§     mixins:用于组件的一个可选的用逗号分隔的混入组件(mixins)的列表。
这些属性指定在t:命名空间里(如,t:id="clear")。
如果id属性被忽略,Tapestry会给这个元素赋一个唯一id。
其他属性用于绑定组件的参数(bind parameters of the component),这些可能是正式参数或非正式参数。正式参数会有一个默认的绑定前缀(通常是"prop:"),非正式参数假定为字面的(如,"literal:"绑定前缀)。
对于其他所有属性,t:前缀是可选的。一些用户实现一个用于Tapestry模板文件校验的构建程序…此时,任何Tapestry相关的属性,非底层DTD或scheme定义的属性,应该在Tapestry的命名空间里,避免产生校验错误。
Tapestry组件元素的开始和结束标签定义了组件的body,这常见于一些组件封入到另外的组件body里。
 
<t:form>
<t:errors/>
<t:label for="userId"/>
<t:textfield t:id="userId"/>
<br/>
<t:table for="password"/>
<t:passwordfield t:id="password"/>
<br/>
<input type="submit" value="Login"/>
</t:form>
在一些情况下,组件需要某种闭合标签;比如,以上所有字段域组件如果没有被Form组件所封闭将会抛出一个运行时异常。
我们有可能将Tapestry组件放置在子包(subclasses?)里。比如,应用中有一个包org.example.myapp.components.ajax.Dialog。这个组件正常的类型名是"ajax/dialog"(因为它在ajax子文件夹下),这个名字是有问题的,因为它不能通过元素名<t:ajax/dialog>有效地定义XML元素。此时,我们使用句点替换斜线——<t:ajax.dialog>。
隐式标识(invisibleInstrumentation
Tapestry中一个突出的特性是隐式标识(invisible instrumentation),用来标记普通的HTML元素为组件。隐式标识可以让模板更加简洁及更好的可读性。
Tapestry 5中,我们使用命名空间id或类型属性来标记一个任意的元素为组件,如下:
<p>
Merry Christmas:
<span t:type="Count" end="3">
Ho!
</span>
</p>
id、type和mixins属性必须放在Tapestry的命名空间里。任何其他的属性可以在Tapestry命名空间里或默认的命名空间里。
Placing an attribute in the Tapestry namespace is useful when the attribute is not defined for the element being instrumented.
当被标识的元素属性未被定义时,将这个属性放入Tapestry的命名空间里是有用的。
只指定t:id属性而不在模板或类中提供明确的类型也是有效的。些种情况,Tapestry会使用Any组件,它有点像是任何其他组件的一种替代。
在大多数情况下,在普通内嵌组件和隐式标识组件之间选择是一个美学问题。少数情况下,如Loop组件,其行为决定于你的选择。当Loop组件使用隐式标识的方式时,将会在其body外围呈现标签及任何非正式参数。因此,比如:
<table>
<tr t:type="loop" source="items" value="item" class="prop:rowClass">
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.quantity}</td>
</tr>
</tabel>
这里,loop组件并入<tr>元素里,它将对每一个列表项呈现一个<tr>,以及在<tr>中输出一个动态的class属性。

Tapestry 5 组件模板相关推荐

  1. 如何在组件模板中选择元素?

    本文翻译自:How can I select an element in a component template? Does anybody know how to get hold of an e ...

  2. 动态添加组件_使用vue.js的动态组件模板

    最近刚做完建站工具,准备总结里面使用到的一些技巧,同时会做一版简化的放在 github上. 先来一篇翻译的文章,和我在项目中使用的动态组件思路一样,不过缺少了演化的过程,直接给出了最终的解决方案.这篇 ...

  3. Vue.js 定义组件模板的七种方式

    转载自  Vue.js 定义组件模板的七种方式 在 Vue 中定义一个组件模板,至少有七种不同的方式(或许还有其它我不知道的方式): 字符串 模板字面量 x-template 内联模板 render ...

  4. [vue] vue为什么要求组件模板只能有一个根元素?

    [vue] vue为什么要求组件模板只能有一个根元素? '为什么只能有且只有一个根元素'于是我花了二十多分钟去找了一下答案......竟然没有找到答案....好的现在我来说说我的理解,如果有不对的地方 ...

  5. [vue] 写出多种定义组件模板的方法

    [vue] 写出多种定义组件模板的方法 1.字符串 2.模板字面量 3.<script type="x-template"></script> 4.文件组件 ...

  6. vue学习-v-if v-for优先级、data、key、diff算法、vue组件化、vue设计原则、组件模板只有一个根元素、MVC.MVP,MVVM

    1:v-if和v-for哪个优先级更高?如果两个同时出现,应该怎么优化得到更好的性能? //在vue页面中 同时使用v-for与v-if后,打印渲染函数. console.log(app.$optio ...

  7. CREO:CREO软件中如何设置和使用各种标准模板文件(asm组件模板、drw工程图模板、prt零件模板)、零件模板的定制、创建零件自动产生绘图、绘图模板的定制之详细攻略

    CREO:CREO软件中如何设置和使用各种标准模板文件(asm组件模板.drw工程图模板.prt零件模板).零件模板的定制.创建零件自动产生绘图.绘图模板的定制之详细攻略 目录

  8. Vue.js 使用script或template标签创建组件模板内容

    为了使HTML代码和JavaScript代码是分离的,便于以后的阅读和维护,我们可以并建议使用<script>或<template>标签创建组件模板内容. <!DOCTY ...

  9. elementui Transfer组件 模板

    elementui Transfer组件 模板 1.效果 2.代码实现 1.效果 2.代码实现 <div class="transfer"><!-- 穿梭框 -- ...

最新文章

  1. VUE3.0 二. vue-cli3 配置指南
  2. CV:利用cv2+dlib库自带frontal_face_detector(人脸征检测器)实现人脸检测与人脸标记之《极限男人帮》和《NBA全明星球员》
  3. VS2008编译boost库
  4. linux游戏调试,LINUX游戏服务器的安装与调试.doc
  5. linux通过bg后台执行作业
  6. 周口a货翡翠,泸州a货翡翠
  7. C#获取周一、周日的日期 函数类
  8. java 生成复杂的word_Java 动态生成复杂 Word
  9. 几组数据的相关性python_Python数据相关系数矩阵和热力图轻松实现(参数解释)...
  10. java mysql 博客园_JAVA基础--MySQL
  11. 调试经验——用XML格式定义Excel (.xls格式)文件 (XML Spreadsheet format in Excel)
  12. 量化交易实战【1】自己搭建一个的股票交易回测框架,并通过均线择时策略进行回测
  13. 【NOIP2011提高组】观光公交
  14. NGINX反向代理缓存
  15. 华为智慧屏 鸿蒙如何,抛开鸿蒙 华为智慧屏V65作为电视合格吗?
  16. ubuntu 黑体_Ubuntu 黑体解决方案
  17. tf.contrib
  18. c语言 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? 待分析过程
  19. 门户网站常用SEO策略及操作规范
  20. 免费学习的Linux主机

热门文章

  1. PyQt——1. 简单认识PyQt及Python3.7安装QtDesigner
  2. BUMO:BU Firework超级节点实时竞选系统
  3. 使用exe4j+inno setup打包exe文件踩坑记录
  4. linux定时删除或者压缩日志文件
  5. OCR/STR生僻字数据训练 | PaddleOCR的Fine-tune常见问题汇总(3)
  6. 身份证号第18位(效验码)计算方法 用于检测身份证号是否正确
  7. 我喜欢你时的内心活动
  8. caffe中forward过程总结
  9. texturepacker图片打包偶然出现的错误
  10. linux find 隐藏,使用find命令查找Linux中的隐藏文件的方法