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.
OpenShift Commons Paris - Choose Your Own Observability Adventure
Grails Layouts & Sitemesh
1. Chicago, October 19 - 22, 2010
Grails Layouts & Sitemesh
Colin Harrington – Object Partners
Sitemesh :: sitemesh.org
2. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
whoami
Colin Harrington
Senior Consultant
colin.harrington@gmail.com
colin.harrington@objectpartners.com
3. 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+)
4. 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
5. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Rich View layer
GSP
Taglibs
Page Directives
Expressions
Views
Templates
...
6. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Grails Layouts
Templating only goes so far...
view + layout
DRY
7. 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”
~ Wikipedia
http://en.wikipedia.org/wiki/Java:_View_Technologies_and_Frameworks
http://en.wikipedia.org/wiki/SiteMesh
8. 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/
9. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Mesh!
← Layout
Views →
Rendered
Result →
10. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Demo
11. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
12. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
21. static layout
Static property on the controller
class BookController {
static layout = 'customLayout'
def list = { … }
}
This will trigger
grailsapp/views/layouts/customLayout.gsp for all
of the controller actions in the BookController
(meta.layout has first precedence)
22. ${controller}/${action} convention
Controller & Controller Action Convention
class BookController {
def list = { … }
}
grailsapp/views/layouts/book/list.gsp
If not → it looks for:
grailsapp/views/layouts/book.gsp
Otherwise it gives up and doesn't decorate the Page
23. ${controller}/${action} convention
Controller & Controller-Action Convention
class BookController {
def list = { … }
}
grailsapp/views/layouts/book/list.gsp
If not → it looks for:
grailsapp/views/layouts/book.gsp
26. 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>
27. 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>
28. 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"/>
29. 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>
30. 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')}
31. 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 -->
32. 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" />
33. 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>
34. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Q&A
35. SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.
Thank you!