和你编写代码相似,你编写的页面也能够由多个小的片段组合而成,这些小的片段本身也能够由更小的片段构成。这些小片段一般是能够在其他页面反复使用的:有些部分能够用在全部页面,而有些部分是某些页面特定的。本篇介绍怎样使用这些可重用的小模板来构成整个页面。
Includes
到眼下为止的样例,我们仅仅显示了HTML的片段,没有实例显示整个页面。以下我们给出完整的显现产品列表的代码和模板:

1 def catalog() = Action {
2     val products = ProductDAO.list
3     Ok(views.html.shop.catalog(products))
4 }

相应的页面模板app/views/products/catalog.scala.html

1 @(products: Seq[Product])
2 <!DOCTYPE html>
3 <html>
4     <head>
5         <title>paperclips.example.com</title>
6         <link href="@routes.Assets.at("stylesheets/main.css")"
7         rel="stylesheet">
8     </head>
9     <body>
10         <div id="header">
11             <h1>Products</h1>
12         </div>
13         <div id="navigation">
14             <ul>
15                 <li><a href="@routes.Application.home">Home</a></li>
16                 <li><a href="@routes.Shop.catalog">Products</a></li>
17                 <li><a href="@routes.Application.contact">Contact</a></li>
18             </ul>
19         </div>
20         <div id="content">
21             <h2>Products</h2>
22             <ul class="products">
23             @for(product <- products) {
24                 <li>
25                     <h3>@product.name</h3>
26                     <p class="description">@product.description</p>
27                 </li>
28             }
29             </ul>
30         </div>
31         <footer>
32             <p>Copyright paperclips.example.com</p>
33         </footer>
34     </body>
35 </html>

这样我们就定义了一个完整的HTML页面,可是我们在当中加入了不少和显示产品列表不直接相关的标记,比方Catalog不须要知道菜单是怎样显示的。页面模块化和重用性不高。
一般来说,一个action方法仅仅应负责终于页面的内容部分。对于非常多站点来说,页头,页脚,导航条在不同页面是通用的,例如以下图:

在这个页面样式中,Header,Navigation,Footer一般是不变的,须要变化的部分是由Page Content指定的部分。

因此我们能够把之前产品列表页面模板中的导航条部分抽取出来单独定义一个navigation页面模板:
views/navigation.scala.html

1 @()
2 <div id="navigation">
3     <ul>
4         <li><a href="@routes.Application.home">Home</a></li>
5         <li><a href="@routes.Shop.catalog">Catalog</a></li>
6         <li><a href="@routes.Application.contact">Contact</a></li>
7     </ul>
8 </div>

然后改动之前的catelog.scala.html

1 @(products: Seq[Product])
2 <!DOCTYPE html>
3 <html>
4     <head>
5         <title>paperclips.example.com</title>
6         <link href="@routes.Assets.at("stylesheets/main.css")"
7         rel="stylesheet">
8     </head>
9     <body>
10         <div id="header">
11             <h1>Products</h1>
12         </div>
13         @navigation()
14         <div id="content">
15             <h2>Products</h2>
16             <ul class="products">
17             @for(product <- products) {
18                 <li>
19                     <h3>@product.name</h3>
20                     <p class="description">@product.description</p>
21                 </li>
22             }
23             </ul>
24         </div>
25         <footer>
26             <p>Copyright paperclips.example.com</p>
27         </footer>
28     </body>
29 </html>

这个改动使得我们的页面变得更好,由于Catalog页面无需再知道怎样显示导航条,这样的把部分页面模板抽取出来单独写成一个可反复使用页面模板的方法叫”includes”,而抽取出来的模板叫”include”。

Layouts
前面的include使得我们的页面模板变好了,可是还是有改进的余地。我们能够看到Catelog页面还是显示整个页面,比方HTML DocType,head等等,这部分不应该由Catalog来负责显示。前面页面模板仅仅有div content部分由Catalog来显示:

1 <h2>Products</h2>
2 <ul class="products">
3 @for(product <- products) {
4     <li>
5         <h3>@product.name</h3>
6         <p class="description">@product.description</p>
7     </li>
8 }
9 </ul>

其他部分都应该放在Catalog 模板之外。我们也能够使用之前的include技术,但不是最理想的。假设我们使用”include”技术,那么我们须要另外两个新的模板,一个为Content前面部分的内容,另外一个模板为Content后面部分的内容。这样的方法不是非常好,由于这些内容应该是放在一起的。
幸运的是使用Scala的组合功能,Play支持抽出全部的内容到一个模板中,从catalog.scala.html 模板中抽出全部不应由catalog负责的部分,到一个布局模板:

1 <!DOCTYPE html>
2 <html>
3     <head>
4         <title>paperclips.example.com</title>
5         <link href="@routes.Assets.at("stylesheets/main.css")"
6         rel="stylesheet">
7     </head>
8     <body>
9         <div id="header">
10             <h1>Products</h1>
11         </div>
12         @navigation()
13         <div id="content">
14           // Content here
15         </div>
16         <footer>
17             <p>Copyright paperclips.example.com</p>
18         </footer>
19     </body>
20 </html>

我们把这部分模板存放在app/views/main.scala.html中,要使得这个模板变成能够重用的,我们为它定义一个參数content,其类型为html,改动例如以下:

1 @(content: Html)
2 <!DOCTYPE html>
3 <html>
4     <head>
5         <title>paperclips.example.com</title>
6         <link href="@routes.Assets.at("stylesheets/main.css")"
7         rel="stylesheet">
8     </head>
9     <body>
10         <div id="header">
11             <h1>Products</h1>
12         </div>
13         @navigation
14         <div id="content">
15         @content
16         </div>
17         <footer>
18             <p>Copyright paperclips.example.com</p>
19         </footer>
20     </body>
21 </html>

使用这个模板如同调用Scala函数类型,views.html.main(content) ,使用这个布局模板,我们改动catelog页面例如以下:

1 @(products: Seq[Product])
2 @main {
3     <h2>Products</h2>
4     <ul class="products">
5     @for(product <- products) {
6         <li>
7             <h3>@product.name</h3>
8             <p class="description">@product.description</p>
9             }
10     </ul>
11 }

假设有须要,我们能够为main布局模板加入很多其他的參数,比方将title也作为參数,
比方把

1 @(content: Html)
2 <html>
3     <head>
4     <title>Paper-clip web shop</title>

改动成

1 @(title: String)(content: Html)
2 <html>
3     <head>
4     <title>@title</title>

还能够给參数定义缺省值,比方:

1 @(title="paperclips.example.com")(content: Html)

这样改动能够进一步參数化布局模板,通用性更强。

很多其他Play教程请訪问http://www.imobilebbs.com/

Play Framework Web开发教程(33): 结构化页面-组合使用模板的更多相关文章

  1. web开发 c/s结构 和 b/s结构

    web开发 c/s结构 和 b/s结构 c/s结构 --client/server 客户端/服务器机构 如qq b/s结构 -- browser/server 浏览器/服务器结构 如网站 mvc设计 ...

  2. cuSPARSELt开发NVIDIA Ampere结构化稀疏性

    cuSPARSELt开发NVIDIA Ampere结构化稀疏性 深度神经网络在各种领域(例如计算机视觉,语音识别和自然语言处理)中均具有出色的性能.处理这些神经网络所需的计算能力正在迅速提高,因此有效 ...

  3. XAF应用开发教程(八) 汉化与多国语言支持

    使用了XAF开发时,汉化是一个比较常的问题. 要实现汉化很简单: 1.在这里下载汉化资源文件.这里演示的版本是15.1.X的 2.文件下载后将:文件解压到目录    <你的项目>\BIN\ ...

  4. [置顶] Java Web开发教程来袭

    Java Web,是用Java技术来解决相关web互联网领域的技术总和.web包括:web服务器和web客户端两部分.Java在客户端的应用有java applet不过现在使用的很少,Java在服务器 ...

  5. 勤拂拭软件 java web 开发教程(1) - 开发环境搭建

    勤拂拭软件系列教程 之 Java Web开发之旅(1) Java Web开发环境搭建 1 前言 工作过程中,遇到不少朋友想要学习jsp开发,然而第一步都迈不出,连一个基本的环境都没有,试问,如何能够继 ...

  6. H5中使用Web Storage来存储结构化数据

    在上一篇对Web Storage的介绍中,可以看到,使用Storage保存key—value对时,key.value只能是字符串,这对于简单的数据来说已经够了,但是如果需要保存更复杂的数据,比如保存类 ...

  7. java web 开发教程(1) - 开发环境搭建

    勤拂拭软件系列教程 之 Java Web开发之旅(1) Java Web开发环境搭建 1 前言 工作过程中,遇到不少朋友想要学习jsp开发,然而第一步都迈不出,连一个基本的环境都没有,试问,如何能够继 ...

  8. 网页布局WEB标准的HTML结构化

    您正在学习WEB标准CSS网页布局吗?是不是还不能完全掌握纯CSS布局?通常有两种需要您特别注意: 第一种可能是你还没有理解CSS处理页面的原理.在你考虑你的页面整体表现效果前,你应当先考虑内容的语义 ...

  9. Twisted web开发教程

    最近在网上看到一篇twisted web开发文章,将它实践了一下,twisted 提供基本的url路由 和 控制器,模板与模型需要外部扩展 1.目录浏览 2.get请求 3.url路由 4.接受带参数 ...

随机推荐

  1. C#。3.1 循环(叠加、穷举)

    循环. for 循环 嵌套的应用, 迭代.穷举 一.迭代法 每次循环都是从上次运算结果中获得数据,本次运算的结果都是要为下次运算做准备.例:1.100以内所有数的和. int sum = 0; for ...

  2. html表格标签与属性

    标记:  标 记  说 明 <Table> 表格标记 <Tr> 行标记 <Td> 单元格标记  <Th> 表头标记 <Table>标记属性: ...

  3. HTML 5 与HTML 4 的区别

    (1)HTML 5 与HTML 4 的相比,语法的改变,以下四个方面: 字符编码改变举例: 省略标记值: (2)新增和废弃的元素 (3)新增html全局属性 (1)指定元素是否可编辑 (2)指定页面是 ...

  4. Android WifiDirect学习(一)

    WiFi Direct基本介绍 Wi-Fi Direct标准允许无线网络中的设备无需通过无线路由器即可相互连接.与蓝牙技术类似,这种标准允许无线设备以点对点形式互连,不过在传输速度与传输距离方面则比蓝 ...

  5. excel运行最多行数

    2003及以前版本为65536(即6万多)行,256列2007版:1048576(即1百零多万)行,16384(即1千多)列

  6. 怎么用C#获取Scenario step在specflow里

    公司最近在用specflow 这种BDD的模式,但PM还是想把case再存进TestManager里面一份儿一遍后期集成TestManager 自动runcase用.所以我们需要获取每个scenari ...

  7. jq原创弹出层折叠效果

    弹出层效果很多网站上都用到,今天就整理最近项目里用到的一个小效果,点击折叠弹出一个层给用户填写信息.弹出层代码都是jq动态创建,每个人写法都不一样,需求也不一样,所有选择符合自已的即可. html: ...

  8. Python读取Yaml文件

    近期看到好多使用Yaml文件做为配置文件或者数据文件的工程,随即也研究了下,发现Yaml有几个优点:可读性好.和脚本语言的交互性好(确实非常好).使用实现语言的数据类型.有一个一致的数据模型.易于实现 ...

  9. 对于Android的线程和线程池的理解

    Android的消息机制,主要是指Handler的运行机制,Handler的运行需要底层的MessageQueue 和 Looper的支撑,MessageQueue中文名消息队列,它的内部存储了一组消 ...

  10. Effective Java Item3:Enforce the singleton property with a private constructor or an enum type

    Item3:Enforce the singleton property with a private constructor or an enum type 采用枚举类型(ENUM)实现单例模式. ...