Showing posts from December, 2012

Using database migrations plugin from within another plugin

The plugin infrastructure provides Grails with great power in how to structure the code base for their applications. For example, if you had to make customizations to your project for a particular client, you could place all your core code in a plugin and have a default and a custom application depending on that plugin. For whatever reason you decide in having a "core" plugin, you might encounter a few bumps in the process. One such bump involves the database migrations plugin. By default the database plugin expects the migration changelogs to be in grails-app/migrations. It is possible to change this location via the configuration config.grails.plugin.databasemigration.changelogLocation, but this requires knowing the location of plugin. So one solution is to put code like the following somewhere in your plugin: Note that in my case, I'm using the platform-core-plugin so it seems appropriate to put it in the doWithConfig closure of my Plugin definition file.

Modularize/partition Grails config files

If you find that your Config.groovy is getting large, you can split it into multiple files using the same mechanism that might already be using to include an external file. So your Config.groovy may already have something like the following defined: One might expect files in the conf directory that follow the convention of ending in Config.groovy of being automatically included but this in not the case. I imagine the reason is a question of precedence - and a lack of clarity thereof. If two files in the conf directory ending in Config.groovy defined the same property which one would win? So only the Config.groovy file is auto-read by Grails, and within this file you can define other Config files to include. It's not very convention over configuration, but you can understand why. The files to include can be defined in one of two lists. grails.config.locations and grails.config.default.locations. Files defined in grails.config.locations are parsed after the property definitions …

AngularJs and SpinJs (in Coffeescript)

SpinJs is a nice Javascript based way to creating a busy/loading spinner on your webpage. I'm going to quickly go through how you might integrated SpinJs with an AngularJs app so that the spinner appears when an Ajax request is sent, and disappears when the Ajax response is received. First we will create and add interceptors. AngularJs makes this task incredibly easy and elegant. We will add the interceptors at configuration time to the httpProvider. As you can see in the above we have only put annoying alerts whenever http requests are send or received. Users would not appreciate if we stopped here! Next we will define the logic to display and hide the spinner from SpinJs. We will define it as a Provider so that it will be available to us at Configuration time. All Providers are required to expose a $get() function, but as we don't need to create multiple instances, we return null. Other than that, the above should be pretty straight forward. We store a reference to the…

Multiple environment blocks in Grails config files

As your Grails app grows, so will your config file. At some stage you might decide to make it all neat and tidy - maybe split it out in to multiple Config files. In this process you might find yourself (quite naturally) calling the environment closure multiple times. Take this example Config.groovy: environments { development { theme = 'funky' } } .... // Lastly add external configs environments { production { grails.config.locations << "file:$userHome/.cfg/app-prod.groovy" } } In the above example, when you try access grailsApplication.config.theme you will not see the expected result (funky). The reason is that the second environments block has overwritten the first one. This is a known "bug" in the Groovy ConfigSlurper. There is an active Jira and even patch submitted but it might be a while before that fix gets in. In the meantime a workaround can be to put all your app specific configuration within the grails config. So…