(A3)Tapestry Core:Component Templates

  <o:p></o:p>

本文翻译出处 http://tapestry.apache.org/tapestry5/tapestry-core/guide/templates.html本人翻译目的是用来学习Tapestry5的,共享出来希望大家批评指正。计划持续翻译。

chinajavawolf 

<o:p></o:p> 

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

你可能感兴趣的:(apache,html,Ajax,嵌入式,tapestry)