Grails WEB层 标签库

 

6.3 标签库

Java Server Pages JSP) 一样,GSP支持定制tag库的概念.不同于JSP,Grails标签库机制是简单的,优雅的,在运行时完全可重载的.

创建一个标签库是相当简单的,创建一个以规约TagLib结尾的一个Groovy类,并把它放置于grails-app/taglib目录里:

 

class SimpleTagLib {

}

现在,为了创建一个标签,简单的创建属性并赋值一个带有两个参数的代码块:标签属性和主体内容:

 

class SimpleTagLib {
	def simple = { attrs, body ->

} }

attrs属性是一个简单的标签属性map,同时body是另一可调用的代码块,它返回主体内容:

 

class SimpleTagLib {
	def emoticon = { attrs, body ->
	   out << body() << attrs.happy == 'true' ? " :-)" : " :-("	
    }
}

正如以上所显示的,这里有个隐式的out变量,它引用了输出Writer,可以用来附加内容到响应中. 然后,你可以在你的GSP内简单的引用这个标签而不需要任何导入:

 

<g:emoticon happy="true">Hi John</g:emoticon>

 

6.3.1 变量与作用域

在标签库的作用域中包含了一些预先定义好的变量:

  • actionName - 当前执行的操作(action)名
  • controllerName - 当前执行的控制器(controller)名
  • flash - The flash 对象
  • grailsApplication - The GrailsApplication实体
  • out - The response writer for writing to the output stream
  • pageScope - pageScope 对象引用,用于GSP渲染(即. binding)
  • params - The params 对象,用于取得请求参数
  • pluginContextPath - 插件上下文路径 ,它包含标签库
  • request - HttpServletRequest实体
  • response - HttpServletResponse实体
  • servletContext - javax.servlet.ServletContext实体
  • session - HttpSession实体

 

6.3.2 简单标签

作为演示,早先的示例只不过是写了个没有主体只有输出内容的简单标签。另一个示例是一个 dateFormat 样式标签:

 

def dateFormat = { attrs, body ->
	out << new java.text.SimpleDateFormat(attrs.format).format(attrs.date)
}

上面使用了Java的SimpleDateFormat类来格式化一个date,然后把它写入响应。随后,这个标签能像下列这样在GSP中使用:

 

<g:dateFormat format="dd-MM-yyyy" date="${new Date()}" />

有时。你需要用简单的标签把HTML标签(mark-up)写入到响应中。一个方法是直接嵌套内容:

 

def formatBook = { attrs, body ->
    out << "<div id="${attrs.book.id}">"	
    out << "Title : ${attrs.book.title}"	
	out << "</div>"
}

虽然,这个方法可能很诱人,但不是非常的简洁。一个更好的方法将是复用render标签:

 

def formatBook = { attrs, body ->
    out << render(template:"bookTemplate", model:[book:attrs.book])	
}

然后,这个单独的GSP模板做了实际的渲染工作.

6.3.3 逻辑标签

一旦一组条件满足,你同样可以在标签的主体中创建仅仅用来输出的逻辑标签。一个这样的例子可能是一组安全标签:

 

def isAdmin = { attrs, body ->
     def user = attrs['user']
     if(user != null && checkUserPrivs(user)) {
           out << body()
     }
}

上面的标签检查用户是否为管理人员,如果他/她有正确设置的访问权限只输出主体内容:

 

<g:isAdmin user="${myUser}">
    // some restricted content
</g:isAdmin>

 

6.3.4 迭代标签

迭代标签同样普通,因为你可以多次调用主体:

 

def repeat = { attrs, body ->
    attrs.times?.toInteger().times { num ->
        out << body(num)
    }
}

在这个示例中,我们检查一个times属性,假如存在,把它转换为一个数字,然后使用Groovy的times方法:

 

<g:repeat times="3">
<p>Repeat this 3 times! Current repeat = ${it}</p>
</g:repeat>

注意,我们是怎么样在这个示例中使用隐式的it变量来引用当前的数字。这个过程是因为在迭代内部我们调用了传递进入当前值的主体:

 

out << body(num)

那个值然后被作为默认的it变量传递给标签,然而,假如你有嵌套标签便会导致冲突,因此,你将可能替换主体使用的变量名:

 

def repeat = { attrs, body ->
	def var = attrs.var ? attrs.var : "num"
    attrs.times?.toInteger().times { num ->
        out << body((var):num)
    }
}

这里,我们检查是否存在一个var属性,如果存在的话,将其作为body调用的参数:

 

out << body((var):num)

 

注意,变量名围绕的圆括号的使用.假如你省略,Groovy会认为你使用了一个String关键字,而不是引用这个变量它自己.

现在,我们可以改变这个标签的使用方法,如下:

 

<g:repeat times="3" var="j">
<p>Repeat this 3 times! Current repeat = ${j}</p>
</g:repeat>

注意,我们是怎么样使用var属性来定义j变量名,随后,我们可能在标签主体类引用这个变量.

6.3.5 标签命名空间

默认情况下,标签被添加到默认的Grails命名空间,并在GSP页面中和 g: 前缀一起使用。然而,你可以指定一个不同的命名空间,通过在你的 TagLib 类中添加一个静态属性:

 

class SimpleTagLib {
    static namespace = "my"

def example = { attrs -> … } }

这里,我们指定了一个命名空间my,因此,稍后在GPS页面中标签库中的标签引用会像这样:

 

<my:example name="..." />

前缀和静态的命名空间属性值一样.命名空间对于插件特别有用.

命名空间内的标签可以作为方法调用,使用命名空间作为前缀来执行方法调用:

 

out << my.example(name:"foo")

可用于GSP,控制器或者标签库.

6.3.6 使用JSP 标签库

除了GSP提供的简单标签库机制, 你也可以在GSP中使用JSP标签.通过taglib指令来简单声明你需要的JSP标签:

 

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

随后,你可以想任何其他标签一样来使用它:

 

<fmt:formatNumber value="${10}" pattern=".00"/>

额外的好处是,你可以把JSP标签当方法调用 :

 

${fmt.formatNumber(value:10, pattern:".00")}

你可能感兴趣的:(Web,jsp,Flash,grails,groovy)