Upload
colin-harrington
View
12.454
Download
2
Embed Size (px)
DESCRIPTION
A deep dive on how Grails uses Sitemesh and explore integration/customization points as well as some light live-coding examples of how to use the apply layout tag in conjunction with layouts to achieve a very flexible and intuitive approach to developing DRY applications with Grails.
Citation preview
Chicago, October 19 - 22, 2010
Grails Layouts & Sitemesh
Colin Harrington – Object Partners
Sitemesh :: sitemesh.org
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
whoami
Colin Harrington
Senior Consultant
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
When & What
Grails 1.3.5
Groovy 1.7.5
Spring 3.0.3
Servlet 2.5
Sitemesh 2.4 (new to Grails 1.1+)
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
GSP
GSP = Groovy Server Pages
GroovyPage (org.codehaus.groovy.grails.web.pages.GroovyPage)
Part of the
GroovyPagesGrailsPlugin
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Rich View layer
GSP
Taglibs
Page Directives
Expressions
Views
Templates
...
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Grails Layouts
Templating only goes so far...
view + layout
DRY
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Sitemesh
'It is a HTML templating framework based on the "Decoration" model'
”It is a web-page layout and decoration framework and web application integration framework to aid in creating large sites consisting of many pages for which a consistent look/feel, navigation and layout scheme is required”
~ Wikipediahttp://en.wikipedia.org/wiki/Java:_View_Technologies_and_Frameworks
http://en.wikipedia.org/wiki/SiteMesh
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Sitemesh
Orignally Developed in 1999 by Joe Walnes.
Now part of the OpenSymphony Project
Implemented in Java
Can decorate any html so
Compatible with {php, asp, perl, python ...}
http://www.opensymphony.com/sitemesh/
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Mesh!
← Layout
Views →
Rendered Result →
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Demo
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
web.xml
...
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>...GrailsPageFilter</filter-class>
</filter>
...
(org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter)
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
sitemesh.xml
<sitemesh>
<page-parsers>
<parser content-type="text/html"
class="...GrailsHTMLPageParser"/>
<parser
content-type="text/html;charset=ISO-8859-1"
class="...GrailsHTMLPageParser"/>
<parser content-type="text/html;charset=UTF-8"
class="...GrailsHTMLPageParser"/>
</page-parsers>
...
</sitemesh>
(org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser)
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
sitemesh.xml
<sitemesh> ... <decorator-mappers> <mapper class="...GrailsLayoutDecoratorMapper" />
</decorator-mappers></sitemesh>
(org.codehaus.groovy.grails.web.sitemesh.GrailsLayoutDecoratorMapper)
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Triggering layouts
In order of precedence:
meta.layout static 'layout' property on the controller controller/action conventions:
/layouts/${controller}/${action}.gsp /layouts/${controller}.gsp
configured grails.sitemesh.default.layout /layouts/application.gsp
meta.layout
<html><head> <meta name="layout" content="main"/> ...</head><body>...</body></html>
This triggers grails-app/views/layouts/main.gsp
static layout
Static property on the controller
class BookController { static layout = 'customLayout'
def list = { … } }
This will trigger
grails-app/views/layouts/customLayout.gsp for all of the controller actions in the BookController
(meta.layout has first precedence)
${controller}/${action} convention
Controller & Controller Action Convention
class BookController { def list = { … } }
grails-app/views/layouts/book/list.gspIf not → it looks for:
grails-app/views/layouts/book.gsp
Otherwise it gives up and doesn't decorate the Page
${controller}/${action} convention
Controller & Controller-Action Convention
class BookController { def list = { … } }
grails-app/views/layouts/book/list.gspIf not → it looks for:
grails-app/views/layouts/book.gsp
grails.sitemesh.default.layout
// grails-app/conf/Config.groovygrails.sitemesh.default.layout='myLayoutName'
application.gsp
When all else fails:
grails-app/views/layouts/application.gsp
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Basic layout tags
{layoutTitle, layoutHead, layoutBody}
<html><head> <title><g:layoutTitle default="my page" /></title> <g:layoutHead /></head><body> <div class="menu"><!-- common menu here--></div> <div class="body"> <g:layoutBody /> </div></body></html>
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Page properties
View:<html><head> <meta name="layout" content="myLayout" /></head><body onload="alert('hello');">
Page to be decorated</body></html>
Layout (myLayout.gsp):<html><head><g:layoutHead /></head><body onload="${pageProperty(name:'body.onload')}"> <g:layoutBody /></body></html>
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
<g:pageProperty/>
<g:pageProperty name="page.mainNav"/>
<g:pageProperty name="page.mainNav" default="home"/>
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
<g:ifPageProperty/>
<g:ifPageProperty name=”showTheContent”>
This content is only displayed if the page property is present
</g:ifPageProperty>
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
<parameter/>
<parameter name=”myParameter” value=”foo”>
Accessible as a page property
${pageProperty(name: 'page.myParameter')}
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
<content/>
View:
<body>...<content tag="sidebar">
Page specific Sidebar...</content>...</body>
Layout:
<div id="sidebar"><g:pageProperty name="page.sidebar" default=""/></div><!-- #sidebar -->
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
<meta/>
<meta> tags get added as a pageProperty
'meta.propertyName'
<meta name="myProp" content="myContent"/>
<g:pageProperty name="meta.myProp" />
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
<g:applyLayout/>
<g:applyLayout name="fieldsetWrapper">This goes into the layoutBody of 'fieldsetWrapper' layout
</g:applyLayout>
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Q&A
SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Thank you!