Your SlideShare is downloading. ×
Grails In The Wild
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Grails In The Wild

2,655
views

Published on

After developing Grails applications full-time for over a year, I've learned some useful tips, tricks, and common patterns. In this presentation, I'll share with you real world examples of how I've …

After developing Grails applications full-time for over a year, I've learned some useful tips, tricks, and common patterns. In this presentation, I'll share with you real world examples of how I've used
Grails "In the Wild".

It includes details of how to do useful things with the basic tools of Grails, some advanced tricks and patterns, and helpful general rules of thumb to use during Grails development.


0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,655
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
114
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Any global value that your application might need can go in the config file. By default it comes with logger configuration, mime types, and the server URL. Here are some examples of other things I’ve found useful in the config.
  • Your application might use several different date formats depending on the context. I hate having date format strings stored inside classes, even if they are enums or interfaces.

    You might also have different date formats used with JavaScript libraries, so you may need to have different format strings for those.
  • You can store these date formats in the config rather easily. This structure is only one way to do it, but the gist is to get these format values in a structure that you can intuitively remember. You may have string formatters for many different values stored in your config as well.
  • Here is an example of using the date format strings from Config.groovy. We are just providing it to a SimpleDateFormat and parsing it as you would with Java.

    This could be helpful if you are expecting a certain date format from an input field on the client in order to parse it into a Date object.
  • From the GSP, you also have easy access to these formats in order to format Date objects into readable Strings. An easy way to do this is with the build in Grails formatDate tag. We provide it with a format string that comes right out of the config and a date object to format, and the tag will do the formatting work for us.
  • Although the JavaScript language itself does not have date to string formatting functionality, some JavaScript libraries will provide them for you. So you may need to have different date format strings easily accessible within the config to give to these frameworks to work with dates.
  • I don’t like classes that contain a bunch of static final variables that are basically used as containers for global data. Especially if they are in the form of interfaces. These values might be better stored inside its own config file. I’ve had projects with a custom rule engine, so I’ve had a RuleConfig.groovy file that contains the rule configuration for that engine.

    You can include as many external config files like this from any location within your grails application into your Config.groovy rather easily. Having multiple files helps to keep things partitioned and keeps the main config uncluttered.
  • If you specify within the main Config.groovy a list of file locations for external configs just like this, all these external config file values will be included just as if it were in the main config file.
  • The bootstrap is very powerful and seems to be a bid underutilized. It is a place to set up sample data for development or test builds, and also allows a placeholder for metaprogramming to occur.
  • Note that bootstrap will always run, even in production. This is a bit shocking for some developers who think bootstrap is just there for sample data, but you can split bootstrap out by environment in order to set up sample data for dev and test, and do any metaprogramming you might want for all environments.

    This is an excellent place for including something like a StringUtils class and mixing it into the String class.
  • Start loading the bootstrap with data as soon as you get some domain classes built. Try to keep the bootstrap up to date when change things. In many cases you’ll get runtime errors when you run-app because you changed the domain model and forgot to update Bootstrap.

    By “progressive enhancement” I mean that as you add features to your application such as authentication, you’ll want to spend some time setting up bootstrap with roles and users. When you add new components like rules, settings, etc. you’ll also want to update it.

    We’ll talk later about some ways to modify your domain classes as well. But can do metaprogramming to your domain classes or even your controllers and services in bootstrap as well.

    And like I mentioned on the previous slide, you can mixin utility classes
  • There are 2 types of templates in Grails: the templates that help to build the scaffolding, which can be rather complicated, and the normal GSP templates.

    I’m going to assume you have a basic knowledge of how to use templates, but the gist of it is that you can take a chunk out of any GSP you have, save it partially with a _ in front of it, and call the template while sending in a model for it to use. In this way we can render these templates not only from several different GSPs and domains, but from controllers as responses to HTTP requests.
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • I like to use templates with AJAX because it is so easy to render a template from a controller as an HTTP response. Here is the general concept... *animate*

    So there is one template at work here be rendered several times. In the list page, we are rendering it on mouse click from the controller, and when we navigate to the show page, we render it again as a part of the entire page.

    So how do we do this?
  • Transcript

    • 1. MM/d/yyyy m/d/Y MM/d/yyyy HH:mm:ss m/d/Y G:i:s
    • 2. Config.groovy format { javaScript { date="m/d/Y" datetime="m/d/Y G:i:s" } java { date="MM/d/yyyy" datetime="MM/d/yyyy HH:mm:ss" } }
    • 3. SomeController.groovy def update = { ... def fmtStr = grailsApplication.config.format.java.date def format = new SimpleDateFormat(fmtStr) foo.birthDate = format.parse(params.userEnteredDateString) ... foo.save() }
    • 4. editFoo.gsp <g:formatDate format="${grailsApplication.config.format.java.date}" date="${foo.date}"/>
    • 5. editFoo.gsp <script> var now = new Date(); var fmtStr = “${grailsApplication.config.format.js.date”; var nowStr = someFormatTool.format(fmtStr, now); </script>
    • 6. Config.groovy grails.config.locations = [ ‘file:./grails-app/conf/DogConfig.groovy’, ‘file:./grails-app/conf/CatConfig.groovy’ ] DogService.groovy grailsApplication.config.dogConfigRootNode.stuff.each { // dog config here }
    • 7. Config.groovy grails.config.locations = [ ‘file:./grails-app/conf/DogConfig.groovy’, ‘file:./grails-app/conf/CatConfig.groovy’ ] DogService.groovy grailsApplication.config.dogConfigRootNode.stuff.each { // dog config here }
    • 8. Bootstrap.groovy def init = { servletContext -> if (GrailsUtil.environment == 'development') { new Foo(name:‘Steven’).save() new Foo(name:‘Joey’).save() new Foo(name:‘Liz’).save() } String.metaClass.mixin StringUtils }
    • 9. Foo Bar FooBarLink
    • 10. Foo Bar 1 1 1..* 1 FooBarAssignment Foo hasMany FooBarAssignments FooBarAssignments belongsTo Foo FooBarAssignments has Bar
    • 11. Foo Bar 1 1 1..* 1..* FooBarLink Foo hasMany FooBarLinks Bar hasMany FooBarLinks FooBarLink belongsTo Foo & Bar
    • 12. Foo Bar 1 1 1..* 1..* FooBarLink Foo hasMany FooBarLinks Bar hasMany FooBarLinks FooBarLink belongsTo Foo & Bar
    • 13. http://jira.codehaus.org/browse/GRAILS-2896
    • 14. A I L http://jira.codehaus.org/browse/GRAILS-2896 F
    • 15. SomeGrailsPlugin.groovy def doWithSpring = { def config = ConfigurationHolder.getConfig() if (!config.foo) { config.somePluginSetting = ‘on’ } } Config.groovy // override the default plugin value foo = ‘off’
    • 16. Thank you Questions?