Grails taglib and JavaScript file
We use internationalization feature in grails using message tag in GSP pages. However arbitrary Groovy/Grails (e.g. tags) code can not be used in JavaScript as they are not executed on server side. To overcome this I used the following way :
Declare a JSON object in js file or any where else so that this object is global one. Create a global JavaScript function that can populate this JSON object. Here is the sample code:
[javascript]
var i18nmessages={};
function updateConfigurationMap(newConfigurationMap) {
for(key in newConfigurationMap){
i18nmessages[key] = newConfigurationMap[key];
}
/*
//or in jQuery way
jQuery.each(newConfiguration, function(key, val) {
i18nmessages[key] = val
});
*/
}
[/javascript]
Now you can write code like below inside HTML head tag in GSP pages to populate the i18nmessages JSON map:
[groovy]
<script type="text/javascript">
updateConfigurationMap({
noResultError : ‘${message(code:’project.noResultError”)}.encodeAsHTML()’,
rangeError : ‘${message(code:’project.rangeError’, args:[50, 100]).encodeAsHTML()}’,
ajaxCallUrl : ‘${createLink(controller:’myController’, action: ‘myAction’)}’,
deleteImagePath : ‘${resource(dir:’images’, file:’myimage.png’)}’
});
</script>
[/groovy]
After execution of the above GSP code considering that the JavaScript code written above has executed, you can use messages like this in javascript :
[javascript]
function findResult(){
alert("Error occurred during processing : "+i18nmessages.noResultError)
}
function getRemoteData(dataToSend){
/* note that you can not use createLink grails tag here */
jQuery.get(i18nmessages.ajaxCallUrl+"?"+dataToSend, function(response){
// Process response here.
})
}
function insertDeleteImage(){
/* As you can not use resource tag of grails here */
jQuery(‘selector’).append("<img src=’"+ i18nmessages.deleteImagePath +"’ />")
}
[/javascript]
Obviously there is a drawback with this approach that the JavaScript for setting messages can not be cached in browser. But the advantage is that you are free to use arbitrary Server side code to generate messages. As you have noticed in above code snippet the URL for ajax call and image paths generated using Grails tags can not be used inside the js files.
Another idea will be to create separate js files name ending with language suffix(e.g. *-en.js, *-sv.js etc) for each language your app support. Populate the i18nmessages there. Use appropriate js file depending on the request locale(e.g. session.'org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE'
). This way you can enable caching of js files in browser but you are limited to messages with static content only.
Please share your ideas how you solved this situation.
Cheers!
~~Bhagwat Kumar~~
bhagwat(at)intelligrape(dot)com
excellent article, worth the read!