Loading...

December 27, 2011

Grails Goodness: Customize the URL Format

Starting from Grails 2.0 we can change the URL format in our application. Default a camel case convention is used for the URLs. For example a controller SampleAppController with an action showSamplePage results in the following URL /sampleApp/showSamplePage.

We can change this convention by creating a new class that implements the grails.web.UrlConverter interface. Grails already provides the custom UrlConverter grails.web.HyphenatedUrlConverter. This converter will add hyphens to the URL where there are uppercase characters and the uppercase character is converted to lowercase. Our sample controller and action result in the following URL with the HyphenatedUrlConverter: /sample-app/show-sample-page.

Because Grails already provides this UrlConverter it is very easy to configure. We only need to change our configuration in grails-app/conf/Config.groovy. We add the key grails.web.url.converter with the value hyphenated:

// File: grails-app/conf/Config.groovy
...
grails.web.url.converter = 'hyphenated'
...

But we can implement our own class with the grails.web.UrlConverter interface to define our own URL format to be used in the Grails application. The interface only has one method String toUrlElement(String) we need to implement. The input argument is the name of the controller or action that needs to be converted. We cannot see if the value is a controller or action value, the conversion rules will be applied to both controller and action values. The following class is a sample implementation. The controller or action name is first converted to lowercase. Next we add the extension -grails to the controller or action. We make sure the conversion is not already done by checking if the extension is not already in place. This check is necessary because Grails will invoke our UrlConverter several times to map it to the correct controller and action names. And without the check the extension would be added again and again and again, resulting in a 404 page not found error.

// File: src/groovy/customize/url/format/CustomUrlConverter.groovy
package customize.url.format

import grails.web.UrlConverter
import org.apache.commons.lang.StringUtils

class CustomUrlConverter implements UrlConverter {
    private static final String GRAILS_EXTENSION = '-grails'

    String toUrlElement(String propertyOrClassName) {
        if (StringUtils.isBlank(propertyOrClassName)) {
            propertyOrClassName
        } else {
            String lowerPropertyOrClassName = propertyOrClassName.toLowerCase()
            String extendedPropertyOrClassName = addGrailsExtension(lowerPropertyOrClassName)
            extendedPropertyOrClassName
        }
    }

    private String addGrailsExtension(String propertyOrClassName) {
        if (propertyOrClassName.endsWith(GRAILS_EXTENSION)) {
            propertyOrClassName
        } else {
            propertyOrClassName + GRAILS_EXTENSION
        }
    }
}

We have our custom UrlConverter. Now we need to configure our Grails application to use it. This time we don't change the configuration grails-app/conf/Config.groovy, but we add our custom implementation to the Spring configuration in grails-app/conf/spring/resources.groovy. If we use the name with the value of the constant grails.web.UrlConverter.BEAN_NAME for our implementation then Grails will use our custom UrlConverter. We can remove any grails.web.url.converter from Config.groovy, because it will not be used.

// File: grails-app/conf/spring/resources.groovy
import static grails.web.UrlConverter.BEAN_NAME as UrlConverterBean

beans = {
...
    "${UrlConverterBean}"(customize.url.format.CustomUrlConverter)
...
}

We are done. If we start our application then we use the URL /sampleapp-grails/showsamplepage-grails to access the controller SampleAppController and the method showSamplePage() in the controller.