Grails是典型的MVC,其中M(Domain Class)和C(Controller)我们都已经接触过了,现在来看看最后的View。在Grails中,View一般是对应的GSP。
工程的GSP都是存放在工程目录下的grails-app/views中,在Controller一节,我们已经谈过如何定位它的问题,在这里就不再重复。对于初次接触GSP的读者来说,简单地套用JSP语法即可:
这里需要注意的是,缺省表达式不会进行转义。如果想,那么在Config.groovy中添加:grails.views.default.codec="html"。至于转义的作用,在以后的安全部分会进行讨论。
和JSP一样,GSP中也有一系列的预定义变量:
对于这些变量的使用自不必多言,使用完全和JSP的套路一样。当然,GSP中也不会少了标签的份。Grails自身提供了大量的标签供开发者使用,详细的标签库名录请参见开发文档。
GSP标签除了一般的JSP风格用法,还有其他使用方式。总结起来:
GSP中还有template的概念:
template文件内容示例:
<div class="book" id="${book?.id}"> <div>Title: ${book?.title}</div> <div>Author: ${book?.author?.name}</div> </div>
在页面中使用template,引用时按名字去引用不要加下划线:
在Controller中的使用:
Template由于使用频繁,因此Grails给它建立单独的名字空间:tmpl。如:<g:render template="bookTemplate" model="[book:myBook]" />可简写成:<tmpl:bookTemplate book="${myBook}" />。
GSP对于页面布局也提供了支持,这就是Layout。它是以Sitemesh为基础,同样也是GSP文件,文件位于grails-app/views/layouts。Layout定义涉及3个主要元素:
使用示例:
<html> <head> <title><g:layoutTitle default="An example decorator" /></title> <g:layoutHead /> </head> <body onload="${pageProperty(name:'body. <div class="menu"> <!--my common menu goes here? <div class="body"> <g:layoutBody /> </div> </div> </body> </html>
其中,pageProperty,可用于输出目标页的某个属性。
对于Layout的使用,4种方式。
法1:在<head>之间使用<meta name="layout" content="main"></meta>。
法2:使用规约。通过存放位置来确定。当有多个匹配时,以详细的优先使用:
法3:使用Controller的layout属性
class BookController { //该controller相关的所有view都将使用 //grails-app/views/layouts/customer.gsp为Layout static layout = 'customer' def list = { … } }
法4,使用<g:applyLayout>,对内容区域、URL、template应用模板:
<g:applyLayout name="myLayout" template="bookTemplate" collection="${books}" /> <g:applyLayout name="myLayout" url="http://www.google.com" /> <g:applyLayout name="myLayout"> The content to apply a layout to </g:applyLayout>
在GSP中使用inlcude,有以下的方式:
在Layout中,我们还可以使用内容块,这将让我们可以更灵活地使用layout。它的使用分成2部分:
在Layout中使用<g:pageProperty />预留:
<div id="left1"> <g:pageProperty name="page.layout1.left.content"/> </div> <div id="top2"> <div id="toolbar"></div> </div> <div id="center2"> <g:pageProperty name="page.layout2.center.content"/> </div> <div id="bottom2"> <g:pageProperty name="page.layout2.bottom.content"/> </div> <g:pageProperty name="page.other"/>
在内容页中使用<content>填充:
<content tag="layout1.left.content"> <!-- 注意没有page前缀 --> <div id="toc"></div> </content> <content tag="layout2.center.content"> <div id="terminal"></div> </content> <content tag="layout2.bottom.content"> <div id="helpstone"></div> </content> <content tag="other"> <div id="how-to" style="text-align:left;"> ... </div> </content>
在GSP部分的最后,让我们来看看如何在GSP中创建标签库。GSP的标签库是一个Groovy文件,每个闭包代表一个标签。使用grails create-tag-lib来创建,标签位于grails-app/taglib。对于每个标签定义都有两个参数:
标签示例:
class SimpleTagLib { def simple = { attrs, body -> //直接输出,对于这种情况,可直接输出到out //省去body() out << body() << attrs.happy == 'true' ? " :-)" : " :-(" } } <!-- 使用 --> <g:simple happy="...">...</g:simple>
如果想要动态生成传给body的参数键值,这要使用: body((var):num),这将会把val的值作为key。
在Tag中同样有相应的预定义变量:
典型标签例子:
标签库缺省的名字空间为g,你同样可以自定义名字空间:
class SimpleTagLib { static namespace = "my" ... }
在GSP中可以使用JSP标签,步骤:
声明:<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
使用
从1.2起,标签缺省返回:org.codehaus.groovy.grails.web.util.StreamCharBuffer类型,这样可以提高页面展示的效率。之前,返回的是String。从1.2起,标签也可以直接返回对象值。
|