Author: Gonzalo Garcia Jaubert
Version: 0.1.0
The dynamic-themes plugin allows your Grails application to load and render pages with your own theme ( folders with GSP templates and css) dinamically outside the scope of a web request. If you've ever used Tumblr or Wordpress then you know what a theme is and how it works.
You can process models and sections (your own tags) in your themes.
This plugin provides the following feature:
- Easy way to add themes to your project
- Build external gsp and css themes
- Change the style of your pages with external css
- Load external views
- Load external templates
- See DynamicThemesExample application for examples.
- See dynamic-themes official page
- See blog
- And follow @ggjaubert
This plugin is released under the Apache License.
Installing the plugin can be done in one of two ways:
In BuildConfig.groovy, add the dependency to your 'plugins' section:
plugins {
...
compile ':dynamic-themes:0.1'
...
}
Note that the version (0.1 in the example above) should be change to refelect the version you would like to us
Simply run the command grails install-plugin dynamic-themes
. Note that this will install the latest version into the global scope, rather than the compile scope which is slightly cleaner, above.
Edit grails-appl-base-dir/conf/Config.groovy
to add:
dynamicThemes {
development {
resourceController.useCacheControl = true
preprocessor.urlThemes = 'themes'
preprocessor.fileSystemPath = 'web-app/themes'
}
production {
resourceController.useCacheControl = true
preprocessor.urlThemes = 'themes'
preprocessor.fileSystemPath = 'themes'
}
}
You can define values for you development and production enviroment.
- useCacheControl: Override to control the css cached.
- urlThemes: Relative url for themes.
- fileSystemPath: Relative file system path for themes. Default is web-app/themes
After installation you can call the DyncamicThemes script grails dynamic-themes, which will copy several files into your project.
grails dynamic-themes
This script will create a themes folder under web-app and copy to themes into it (default and default2).
You can test the plugin with the next views:
- partialGSPHowTo: Example of partial gsp injection
- GSPHowto: Example of full gsp injection
- cssHowTo: Example of css injection
If you want full examples, visit DynamicThemesExample
Themes are folders with the following example structure:
themeName
- \icons\*.png
- \images\*.png
- themeName.css
- themeName.html
- themeName.snapshot.png
The only expected file is themeName.html. You can see two themes examples in the webapp dir: default and default2.
The default.html file contains a link to webapps\themes\images\grails_logo.png with the next code:
html <img alt="imagen1" src='${ImagesPath}/grails_logo.png'">
This html (a gsp) use the default.css stylesheet:
html <div class="fondodiv">
And show two ways to see a list of elements. First with grails code:
<g:each var="element" in="${elements}">
<h2>${element}</h2>
<hr>
<div class="row">
<div class="span11">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed neque magna, ...
</div>
</div>
</g:each>
And with sections:
<ul>
#beginLoop#
<li>Element: <b>${element}</b>
#endLoop#
</ul>
Using the dynamic-themes plugin in your application requires a few simple steps:
Process your theme and return to view:
def theme = preprocessorService.preprocess(themeName)
[heme: theme]
Optional: If you want to inject sections (see sections):
// Example of sections replace
def elements = "['Post 1', 'Post 2', 'Post 3']"
def sections = ["#beginLoop#": """<g:each var="element" in="${elements}">""", """#endLoop#""": """</g:each>"""]
Optional: If you want to inject models (see models):
def themeName = "default"
def elementsList = ['Post 1', 'Post 2', 'Post 3']
def model = [ImagesPath: preprocessorService.getConfigParams(themeName).urlFolderImages, elements:elementsList]
Optional: Example for a snapshot (see more)
def snap = preprocessorService.getConfigParams(themeName).urlSnapshot
Optional: Process your theme and return to view with your optional params:
def theme = preprocessorService.preprocess(themeName , sections, model)
To inject a dynamic css in your view use the injectCss tag:
<head>
<meta name="layout" content="main">
<title>cssHowTo</title>
<g:injectCss themeName="${themeName}" ImagesPath="true" />
<g:injectCss themeName="${themeName}" ImagesPath="false" model="[var1: 'hello']"/>
</head>
To inject a dynamic html/gsp in your view use the injectGSP tag:
<body>
An css and gsp dynamic-themes example. View source code for the css dynamic-themes.
<g:injectGSP instance="${result}"/>
</body>
When using the plugin you can use the next parameters:
Sections are code replaced before processing. Example:
<ul>
#beginLoop#
<li>Element: <b>${element}</b>
#endLoop#
</ul>
in your controller replace the secctions with your own code with:
// Example of sections replace
def elements = "['Post 1', 'Post 2', 'Post 3']"
def sections = ["#beginLoop#": """<g:each var="element" in="${elements}">""", """#endLoop#""": """</g:each>"""]
You can inject models in your theme. Example:
<g:each var="element" in="${elements}">
<h2>${element}</h2>
<hr>
<div class="row">
<div class="span11">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed neque magna, ...
</div>
</div>
</g:each>
In your controller use:
def themeName = "default"
def elementsList = ['Post 1', 'Post 2', 'Post 3']
def model = [ImagesPath: preprocessorService.getConfigParams(themeName).urlFolderImages, elements:elementsList]
You can inject other files. For example the snapshot of the theme with:
<div class="hero-unit">
<h2>Snapshot for the theme</h2>
<img src="${snapshot}" style="width:200px"/>
</div>
In your controller:
def snap = preprocessorService.getConfigParams(themeName).urlSnapshot
Note: The urlSnapshot is the root of the theme
;0.1.0 Initial version (November 29, 2012)