Grails url mapping localization

This is simple "hack" that allows you to internationalize your url in your Grails (1.2.x) application. Lets say that we have application that is provided in two languages: Polish and English. Create ours controller:

 
FooController {
    def bar {
    }
}
 

In ours locale files (message_pl.properties and message_en.properties) add "locale" param (because grails bug) with code specified for this file (pl, en).

Next step is to create new taglib that will generate internationalized link:

 
class BaseTagLib {
    def localizedLink = { attrs, body ->
        attrs.mapping = message(code:'locale') + StringUtils.toUpperCaseFristLetter(attrs.mapping)
        out << link(attrs, body)
    }
}
 

This Taglib doing nothing than add prefix for name of the route. It use util method StringUtils.toUpperCaseFristLetter, that capitalize first letter of provided string:

 
class StringUtils {
    static def toUpperCaseFristLetter(String text){
        text[0].toUpperCase() + text[1..-1]
    }
}
 

Now we can provide url mappings as:

 
class UrlMappings {
    static mappings = {
        name enGoToFooBar:'/go/to/foo/Bar' {
            controller = 'foo'
            action = 'bar'
        }
 
        name plGoToFooBar:'/idz/do/foo/Bar' {
            controller = 'foo'
            action = 'bar'
        }
    }
}
 

In ours gsp files we can use it like:

 
<g:localizedLink mapping="goToFooBar"><g:message code="text.goToFooBar" /></g:localizedLink>
 

Setting default locale

If you want to set default locale for application, add this definition of LocaleResolver to spring context configuration:

 
localeResolver(SessionLocaleResolver) {
    defaultLocale = new Locale('pl')
    Locale.setDefault (defaultLocale)
}
 

Request.locale Grails bug

If you want to use request.locale to determine current locale - forget abut that. Even in Grails 1.2, if you pass lang parameter there will be no change of this object and it will stay as a default (even if i18n properties file will be changed). Quick fix is to add locale entry in message bundles (maybe, hmmm locale) and use it.

Rendering templates in services

If you want to render gsp template on level of service (or in any other bean), just get org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib bean from spring context, and call method render on it:

 
class FooService {
 
    boolean transactional = false
 
    def grailsApplication
 
    def bar(view, model) {
        render(template:"/templates/emails/${view}", model:model)
    }
 
    private def render(args){
        grailsApplication.mainContext.getBean('org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib').render(args)
    }
}
 

Grails 1.1.2 released

Today was released Grails 1.1.2 . There are some bug fixes and new functionalities (changelog). Rely on Robert Fletcher, version 1.2 will not appear, until Spring 3.0 goes final.

@Validateable – thank you ….

Today I learn about cool feature of Grails, that I missed or maybe it appear recently in documentation. As you probably know, I am talking about @Validateable annotation. Just mark your class with @Validateable and all it instances will provide validation mechanisms, like domain classes and command objects.

Where it can be use? Good example is service level, where the only object that provide such functionality is domain class and initialized command object will be simple POGO, without validation functionality.

Grails 1.1.1 and plugin release problems

Creating plug-in in Grails is easy, but it releasing is not. When I was trying to release my Burning Image plug-in I was hit with two problems. First was "svn: Authentication required" :

Importing project to https://svn.codehaus.org/grails-plugins/grails-burning-image. Please wait...
org.tmatesoft.svn.core.SVNAuthenticationException: svn: Authentication required for ' grails-plugins primary Subversion repository

To work around this problem just add file setting.groovy into your ~/.grails/ directory and add this lines:

grails.plugin.repos.discovery.grailsplugins="https://svn.codehaus.org:443/grails-plugins"
grails.plugin.repos.distribution.grailsplugins="https://svn.codehaus.org:443/grails-plugins"

Now you should be asked about yours credentials after executing:

grails release-plugin "-repository=grailsplugins"

Second problem was error:

Error executing script ReleasePlugin: groovy.lang.MissingMethodException: No signature of method: _PluginDependencies_groovy$_run_closure2.doCall() is applicabl
e for argument types: (java.lang.Boolean, java.lang.String) values: [true, distribution]
gant.TargetExecutionException: groovy.lang.MissingMethodException: No signature of method: _PluginDependencies_groovy$_run_closure2.doCall() is applicable for a
rgument types: (java.lang.Boolean, java.lang.String) values: [true, distribution]
        at gant.Gant$_dispatch_closure4.doCall(Gant.groovy:331)
        at gant.Gant$_dispatch_closure6.doCall(Gant.groovy:334)
        at gant.Gant$_dispatch_closure6.doCall(Gant.groovy)
        at gant.Gant.withBuildListeners(Gant.groovy:344)
        at gant.Gant.this$2$withBuildListeners(Gant.groovy)
        at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
        at gant.Gant.dispatch(Gant.groovy:334)
        at gant.Gant.this$2$dispatch(Gant.groovy)
        at gant.Gant.invokeMethod(Gant.groovy)
        at gant.Gant.processTargets(Gant.groovy:495)
        at gant.Gant.processTargets(Gant.groovy:480)
Caused by: groovy.lang.MissingMethodException: No signature of method: _PluginDependencies_groovy$_run_closure2.doCall() is applicable for argument types: (java
.lang.Boolean, java.lang.String) values: [true, distribution]
        at ReleasePlugin$_run_closure3.doCall(ReleasePlugin.groovy:75)
        at ReleasePlugin$_run_closure1.doCall(ReleasePlugin.groovy:42)
        at gant.Gant$_dispatch_closure4.doCall(Gant.groovy:324)
        ... 10 more

It occurs when I try to execute release plug-in command like this:

grails release-plugin -repository=grailsplugins

Just add " like previously and all should go smoothly.

Burning Image Grails plugin

Today I ended my work over my first Grails plug-in: Burning Image. This simple plug-in for images manipulation provides two types of image scaling, and allows to watermark image. In future i want to add crop option and maybe rounding image corner. If you looking for some more informations or you want to try it you could fine it Google code repository.

Groovy closure – will it work?

Lets say we have Groovy class like this:

 
class Foo {
 
    def bar(myClosure) {
        myClosure(this)
    }
 
   private def bas(myName) {
       println "hello from ${myName}"
  }
}
 

and I am wonder what should happen if I execute this line of code:

 
new Foo().bar {
    it.bas("Steve Zissou")
}
 

Should it throw exception that I want execute private method? But this method is execute inside Foo object instance. So, should it print

hello from Steve Zissou

Unfortunately question is still open because Groovy private method / field bug. Or maybe is time to start using Scala and Lift?

    Grails multiple select binding

    When first time I try to use html select tag with multiple selection, I spent about 1h to figure "how to" because user guide is, hmmm, as is. So, there is my little example:

    Lets create domain objects:

     
    Author {
        String firstName
        String lastName
        static hasMany = [books:Book]
    }
     
     
    Book {
        String title
        static belongsTo = [author:Author]
    }
     

    Author form will contain select with books like this:

     
    <g:select optionKey="id" optionValue="title"  multiple="multiple" name="author.books" id ="author_books" from="${allBooks}" value="${authorInstance?.books*.id}"/>
     

    Multiple select binding to Author.books is now available.

Powered by WordPress with GimpStyle Theme design by Horacio Bella.
Entries and comments feeds. Valid XHTML and CSS.