6.2.4 使用Sitemesh布局 - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith
Version: null
6.2.4 使用Sitemesh布局
Creating Layouts
Grails leverages Sitemesh, a decorator engine, to support view layouts. Layouts are located in thegrails-app/views/layouts directory. A typical layout can be seen below:<html> <head> <title><g:layoutTitle default="An example decorator" /></title> <g:layoutHead /> </head> <body onload="${pageProperty(name:'body.onload')}"> <div class="menu"><!--my common menu goes here--></menu> <div class="body"> <g:layoutBody /> </div> </div> </body> </html>
layoutTitle- outputs the target page's titlelayoutHead- outputs the target page's head tag contentslayoutBody- outputs the target page's body tag contents
创建布局
Grails使用Sitemesh(一个装饰引擎)来支持视图布局。布局位于grails-app/views/layouts目录下边。一个典型的布局可以如下所示:<html> <head> <title><g:layoutTitle default="An example decorator" /></title> <g:layoutHead /> </head> <body onload="${pageProperty(name:'body.onload')}"> <div class="menu"><!--my common menu goes here--></menu> <div class="body"> <g:layoutBody /> </div> </div> </body> </html>
layoutTitle- 输出目标页面的标题(title)layoutHead- 输出目标页面的head标签的内容layoutBody- 输出目标页面的body标签的内容
Triggering Layouts
There are a few ways to trigger a layout. The simplest is to add a meta tag to the view:<html> <head> <title>An Example Page</title> <meta name="layout" content="main" /> </head> <body>This is my content!</body> </html>
grails-app/views/layouts/main.gsp will be used to layout the page. If we were to use the layout from the previous section the output would resemble this:<html> <head> <title>An Example Page</title> </head> <body onload=""> <div class="menu"><!--my common menu goes here--></div> <div class="body"> This is my content! </div> </body> </html>
触发布局
有几种方法来触发一个布局。最简单的一种就是在视图中增加一个meta标签:<html> <head> <title>An Example Page</title> <meta name="layout" content="main" /> </head> <body>This is my content!</body> </html>
grails-app/views/layouts/main.gsp的布局将被用于安排页面。如果我们使用上一小节的布局,那么其输出类似下面所示:<html> <head> <title>An Example Page</title> </head> <body onload=""> <div class="menu"><!--my common menu goes here--></div> <div class="body"> This is my content! </div> </body> </html>
Specifying A Layout In A Controller
Another way to specify a layout is to specify the name of the layout by assigning a value to the "layout" property in a controller. For example, if you have a controller such as:class BookController {
static layout = 'customer' def list() { … }
}grails-app/views/layouts/customer.gsp which will be applied to all views that the BookController delegates to. The value of the "layout" property may contain a directory structure relative to the grails-app/views/layouts/ directory. For example:class BookController {
static layout = 'custom/customer' def list() { … }
}grails-app/views/layouts/custom/customer.gsp template.
在控制器中指定一个布局
另外一种指定布局的方法是在控制器中为"layout"属性赋值一个布局的名称。举一个例子,假设你有如下一个控制器:class BookController {
static layout = 'customer' def list() { … }
}grails-app/views/layouts/customer.gsp布局,这样BookController所有的所有视图将使用此布局。"layout"属性的值还可以包含一个目录结构,不过要相对于grails-app/views/layouts/目录。比如:class BookController {
static layout = 'custom/customer' def list() { … }
}grails-app/views/layouts/custom/customer.gsp模板来装饰。Layout by Convention
Another way to associate layouts is to use "layout by convention". For example, if you have this controller:class BookController {
def list() { … }
}grails-app/views/layouts/book.gsp, which will be applied to all views that the BookController delegates to.Alternatively, you can create a layout called grails-app/views/layouts/book/list.gsp which will only be applied to the list action within the BookController.If you have both the above mentioned layouts in place the layout specific to the action will take precedence when the list action is executed.If a layout may not be located using any of those conventions, the convention of last resort is to look for the application default layout which
is grails-app/views/layouts/application.gsp. The name of the application default layout may be changed by defining a property
in grails-app/conf/Config.groovy as follows:grails.sitemesh.default.layout = 'myLayoutName'grails-app/views/layouts/myLayoutName.gsp.
布局规约
另外一种关联布局的方式是使用"布局规约"。比如,你的控制器如下所示:class BookController {
def list() { … }
}grails-app/views/layouts/book.gsp布局,此布局将会应用于一个BookController的所有视图。此外,你也可以创建一个grails-app/views/layouts/book/list.gsp布局,其用于BookController的list操作。如果你有如上所述的两个布局,那么当list操作被执行时,跟操作相关的布局将优先使用。如果一个布局在这些约定中没有找到,那么此规约的最后顺序是查找应用的缺省布局grails-app/views/layouts/application.gsp。应用的缺省布局名称可以通过修改grails-app/conf/Config.groovy中的属性来改变,比如:grails.sitemesh.default.layout = 'myLayoutName'grails-app/views/layouts/myLayoutName.gsp。Inline Layouts
Grails' also supports Sitemesh's concept of inline layouts with the applyLayout tag. This can be used to apply a layout to a template, URL or arbitrary section of content. This lets you even further modularize your view structure by "decorating" your template includes.Some examples of usage can be seen below:<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>
内联布局
Grails同样支持Sitemesh的内联布局概念,可以使用applyLayout标签来实现。此标签可以将一个布局应用于一个模板,URL或者任意部分的内容。更甚者,通过“装饰”你的模板你可以将你的视图模块化。这些用法的一些示例如下:<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>
Server-Side Includes
While the applyLayout tag is useful for applying layouts to external content, if you simply want to include external content in the current page you use the include tag:<g:include controller="book" action="list" /><g:applyLayout name="myLayout"> <g:include controller="book" action="list" /> </g:applyLayout>
def content = include(controller:"book", action:"list")
服务器端的包含
applyLayout标签可以将布局应用到外部内容,而如果你只想简单地将外部内容包含到当前页面,你可以使用include标签:<g:include controller="book" action="list" /><g:applyLayout name="myLayout"> <g:include controller="book" action="list" /> </g:applyLayout>
def content = include(controller:"book", action:"list")

