(Quick Reference)

6.2.2 GSP标签 - Reference Documentation

Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith

Version: null

6.2.2 GSP标签

Now that the less attractive JSP heritage has been set aside, the following sections cover GSP's built-in tags, which are the preferred way to define GSP pages.

The section on Tag Libraries covers how to add your own custom tag libraries.

All built-in GSP tags start with the prefix g:. Unlike JSP, you don't specify any tag library imports. If a tag starts with g: it is automatically assumed to be a GSP tag. An example GSP tag would look like:

<g:example />

GSP tags can also have a body such as:

<g:example>
   Hello world
</g:example>

Expressions can be passed into GSP tag attributes, if an expression is not used it will be assumed to be a String value:

<g:example attr="${new Date()}">
   Hello world
</g:example>

Maps can also be passed into GSP tag attributes, which are often used for a named parameter style syntax:

<g:example attr="${new Date()}" attr2="[one:1, two:2, three:3]">
   Hello world
</g:example>

Note that within the values of attributes you must use single quotes for Strings:

<g:example attr="${new Date()}" attr2="[one:'one', two:'two']">
   Hello world
</g:example>

With the basic syntax out the way, the next sections look at the tags that are built into Grails by default.

现在没有吸引力的JSP遗留部分已经被废除了,那么接下来的章节,我们将讨论GSP的内置标签,它们是定义GSP页面非常有力的方法。

标签库章节讨论的是如何添加你自己定制的标签库

所有内置的GSP标签都是以前缀g:开始的。跟JSP不同的是,你不需要指定任何的标签库导入。如果一个标签以g:开头,那么将会自动地被当作GSP标签看待。一个GSP的标签的样子如下所示:

<g:example />

GSP标签还可以有一个主体(body),比如:

<g:example>
   Hello world
</g:example>

GSP标签的属性可以使用Groovy表达式,而如果没有明确指定的话,其缺省为一个字符串值:

<g:example attr="${new Date()}">
   Hello world
</g:example>

Map类型也可以作为GSP标签的属性,其一般被用作命名参数风格的语法:

<g:example attr="${new Date()}" attr2="[one:1, two:2, three:3]">
   Hello world
</g:example>

注意!属性里边的字符串值你必须使用单引号:

<g:example attr="${new Date()}" attr2="[one:'one', two:'two']">
   Hello world
</g:example>

基本的语法已经介绍完毕,接下来的章节将是Grails自带的缺省标签了。

6.2.2.1 变量和作用域

Variables can be defined within a GSP using the set tag:

<g:set var="now" value="${new Date()}" />

Here we assign a variable called now to the result of a GSP expression (which simply constructs a new java.util.Date instance). You can also use the body of the <g:set> tag to define a variable:

<g:set var="myHTML">
   Some re-usable code on: ${new Date()}
</g:set>

Variables can also be placed in one of the following scopes:

  • page - Scoped to the current page (default)
  • request - Scoped to the current request
  • flash - Placed within flash scope and hence available for the next request
  • session - Scoped for the user session
  • application - Application-wide scope.

To specify the scope, use the scope attribute:

<g:set var="now" value="${new Date()}" scope="request" />

在GSP中,可以通过set标签来定义变量:

<g:set var="now" value="${new Date()}" />

此处,我们将一个GSP表达式(只是简单地构造一个java.util.Date实例)的结果赋值给now变量。你也可以使用<g:set>标签的主体来定义一个变量:

<g:set var="myHTML">
   Some re-usable code on: ${new Date()}
</g:set>

变量也可以被置于如下的作用域之一:

  • page - 作用于当前页面(缺省)
  • request - 作用于当前请求
  • flash - 置于flash作用域内,因此在下一个请求中是有效的
  • session - 作用于用户会话
  • application - 应用级别的作用域

要指定作用域,要使用scope属性:

<g:set var="now" value="${new Date()}" scope="request" />

6.2.2.2 逻辑和迭代

GSP also supports logical and iterative tags out of the box. For logic there are if, else and elseif tags for use with branching:

<g:if test="${session.role == 'admin'}">
   <%-- show administrative functions --%>
</g:if>
<g:else>
   <%-- show basic functions --%>
</g:else>

Use the each and while tags for iteration:

<g:each in="${[1,2,3]}" var="num">
   <p>Number ${num}</p>
</g:each>

<g:set var="num" value="${1}" /> <g:while test="${num < 5 }"> <p>Number ${num++}</p> </g:while>

GSP也支持逻辑和迭代地标签。ifelseelseif标签用于逻辑,用以处理分支:

<g:if test="${session.role == 'admin'}">
   <%-- show administrative functions --%>
</g:if>
<g:else>
   <%-- show basic functions --%>
</g:else>

eachwhile标签用于迭代:

<g:each in="${[1,2,3]}" var="num">
   <p>Number ${num}</p>
</g:each>

<g:set var="num" value="${1}" /> <g:while test="${num < 5 }"> <p>Number ${num++}</p> </g:while>

6.2.2.3 搜索和过滤

If you have collections of objects you often need to sort and filter them. Use the findAll and grep tags for these tasks:

Stephen King's Books:
<g:findAll in="${books}" expr="it.author == 'Stephen King'">
     <p>Title: ${it.title}</p>
</g:findAll>

The expr attribute contains a Groovy expression that can be used as a filter. The grep tag does a similar job, for example filtering by class:

<g:grep in="${books}" filter="NonFictionBooks.class">
     <p>Title: ${it.title}</p>
</g:grep>

Or using a regular expression:

<g:grep in="${books.title}" filter="~/.*?Groovy.*?/">
     <p>Title: ${it}</p>
</g:grep>

The above example is also interesting due to its usage of GPath. GPath is an XPath-like language in Groovy. The books variable is a collection of Book instances. Since each Book has a title, you can obtain a list of Book titles using the expression books.title. Groovy will auto-magically iterate the collection, obtain each title, and return a new list!

如果你的对象是集合,那么你经常需要排序和过滤。使用findAllgrep标签可以完成这些任务:

Stephen King's Books:
<g:findAll in="${books}" expr="it.author == 'Stephen King'">
     <p>Title: ${it.title}</p>
</g:findAll>

expr属性使用一个Groovy表达式来作为过滤器。grep标签完成类似的任务,比如要过滤对象类:

<g:grep in="${books}" filter="NonFictionBooks.class">
     <p>Title: ${it.title}</p>
</g:grep>

或者使用一个正则表达式:

<g:grep in="${books.title}" filter="~/.*?Groovy.*?/">
     <p>Title: ${it}</p>
</g:grep>

上述示例也展示了GPath用法。Groovy的GPath跟XPath类似。books变量是一个Book实例的集合。因为每一个Book都有title,你可以使用表达式books.title来获取Book标题的列表。Groovy将会自动地对集合迭代,获取每一个标题,最终返回一个新的列表。

6.2.2.4 链接和资源

GSP also features tags to help you manage linking to controllers and actions. The link tag lets you specify controller and action name pairing and it will automatically work out the link based on the URL Mappings, even if you change them! For example:

<g:link action="show" id="1">Book 1</g:link>

<g:link action="show" id="${currentBook.id}">${currentBook.name}</g:link>

<g:link controller="book">Book Home</g:link>

<g:link controller="book" action="list">Book List</g:link>

<g:link url="[action: 'list', controller: 'book']">Book List</g:link>

<g:link params="[sort: 'title', order: 'asc', author: currentBook.author]" action="list">Book List</g:link>

GSP标签也能帮助你来管理控制器和操作的超链接。link标签让你来指定控制器和操作名称对,并且标签会自动生成基于URL映射的链接,即使映射改变了也没有问题,比如:

<g:link action="show" id="1">Book 1</g:link>

<g:link action="show" id="${currentBook.id}">${currentBook.name}</g:link>

<g:link controller="book">Book Home</g:link>

<g:link controller="book" action="list">Book List</g:link>

<g:link url="[action: 'list', controller: 'book']">Book List</g:link>

<g:link params="[sort: 'title', order: 'asc', author: currentBook.author]" action="list">Book List</g:link>

6.2.2.5 表单和字段

Form Basics

GSP supports many different tags for working with HTML forms and fields, the most basic of which is the form tag. This is a controller/action aware version of the regular HTML form tag. The url attribute lets you specify which controller and action to map to:

<g:form name="myForm" url="[controller:'book',action:'list']">...</g:form>

In this case we create a form called myForm that submits to the BookController's list action. Beyond that all of the usual HTML attributes apply.

表单基础

GSP有很多不同的标签来支持HTML表单和字段,不过最基础的还是form标签。常规的HTML表单标签支持controller/action属性,而url属性让你以映射(map)的方式来指定controller和action:

<g:form name="myForm" url="[controller:'book',action:'list']">...</g:form>

在这个示例中,我们创建了一个myForm表单,它将会提交到BookController控制器的list操作。此外HTML的所有通用属性都可以使用。

Form Fields

In addition to easy construction of forms, GSP supports custom tags for dealing with different types of fields, including:

  • textField - For input fields of type 'text'
  • passwordField - For input fields of type 'password'
  • checkBox - For input fields of type 'checkbox'
  • radio - For input fields of type 'radio'
  • hiddenField - For input fields of type 'hidden'
  • select - For dealing with HTML select boxes

Each of these allows GSP expressions for the value:

<g:textField name="myField" value="${myValue}" />

GSP also contains extended helper versions of the above tags such as radioGroup (for creating groups of radio tags), localeSelect, currencySelect and timeZoneSelect (for selecting locales, currencies and time zones respectively).

表单字段

除了轻松地构造表单之外,GSP自定义的标签支持不同的字段类型,包括:

  • textField - 针对类型是'text'的输入字段
  • passwordField - 针对类型是'password'的输入字段
  • checkBox - 针对类型是'checkbox'的输入字段
  • radio - 针对类型是'radio'的输入字段
  • hiddenField - 针对类型是'hidden'的输入字段
  • select - 针对HTML的下拉框(select boxes)

这些标签的value属性都允许使用GSP表达式:

<g:textField name="myField" value="${myValue}" />

GSP还包含上述标签扩展的助手版本,比如radioGroup(用于创建一组radio标签)、localeSelectcurrencySelecttimeZoneSelect(用于选择区域、货币和时区)。

Multiple Submit Buttons

The age old problem of dealing with multiple submit buttons is also handled elegantly with Grails using the actionSubmit tag. It is just like a regular submit, but lets you specify an alternative action to submit to:

<g:actionSubmit value="Some update label" action="update" />

多个提交按钮

处理多个提交按钮这一个古老的问题,也得到优雅的解决,那就是使用Grails的actionSubmit标签。跟常规的提交类似,只不过你可以指定另外一个操作来提交:

<g:actionSubmit value="Some update label" action="update" />

6.2.2.6 标签的方法调用

One major different between GSP tags and other tagging technologies is that GSP tags can be called as either regular tags or as method calls from controllers, tag libraries or GSP views.

Tags as method calls from GSPs

Tags return their results as a String-like object (a StreamCharBuffer which has all of the same methods as String) instead of writing directly to the response when called as methods. For example:

Static Resource: ${createLinkTo(dir: "images", file: "logo.jpg")}

This is particularly useful for using a tag within an attribute:

<img src="${createLinkTo(dir: 'images', file: 'logo.jpg')}" />

In view technologies that don't support this feature you have to nest tags within tags, which becomes messy quickly and often has an adverse effect of WYSWIG tools such as Dreamweaver that attempt to render the mark-up as it is not well-formed:

<img src="<g:createLinkTo dir="images" file="logo.jpg" />" />

One major different between GSP tags and other tagging technologies is that GSP tags can be called as either regular tags or as method calls from controllers, tag libraries or GSP views.

在GSP中以方法调用标签

当标签以方法的方式调用时,其返回一个类似String(一个StreamCharBuffer,有着跟String完全相同的方法)的对象,而不是直接写回到响应器。比如:

Static Resource: ${createLinkTo(dir: "images", file: "logo.jpg")}

这在一个属性内使用标签的时候特别有用:

<img src="${createLinkTo(dir: 'images', file: 'logo.jpg')}" />

在视图技术中,标签内嵌套标签是不被支持的,因为那将会很快导致混乱,而且像Dreamweaver这样所见即所得(WYSWIG)的工具产生不利的效果,因为那会破坏标签的结构良好性:

<img src="<g:createLinkTo dir="images" file="logo.jpg" />" />

Tags as method calls from Controllers and Tag Libraries

You can also invoke tags from controllers and tag libraries. Tags within the default g: namespace can be invoked without the prefix and a StreamCharBuffer result is returned:

def imageLocation = createLinkTo(dir:"images", file:"logo.jpg").toString()

Prefix the namespace to avoid naming conflicts:

def imageLocation = g.createLinkTo(dir:"images", file:"logo.jpg").toString()

For tags that use a custom namespace, use that prefix for the method call. For example (from the FCK Editor plugin):

def editor = fckeditor.editor(name: "text", width: "100%", height: "400")

在控制器和标签库中的以方法调用标签

你可以可以在控制器和标签库中调用标签。命名空间g:的标签调用可以忽略其前缀,并且一个StreamCharBuffer类型的结果被返回:

def imageLocation = createLinkTo(dir:"images", file:"logo.jpg").toString()

命名空间前缀是用以避免名称冲突的:

def imageLocation = g.createLinkTo(dir:"images", file:"logo.jpg").toString()

对于那些使用自定义命名空间的标签,在以方法调用时要使用其前缀。比如(来自FCK 编辑器插件):

def editor = fckeditor.editor(name: "text", width: "100%", height: "400")