Monday, August 1, 2011

Grails Plugins and Default Configs

I've been working on Grails plugins for jQueryUI and YUI2.  One of my ideas was to use a default config within my plugin, which the plugin consumer could override and modify the config values for their usage.

Unfortunately, Grails doesn't provide this feature by default.  You can use the plugin's Config.groovy for settings when you test, but it doesnt work when the plugin is being ran from an app.  Unless...  you do the following.

Lets say your creating the next awesome plugin.  We'll call it Foo.

1.  Create a groovy config file that is unique to your plugin.  Mine is FooConfig.groovy. Inside, put your config values.
fooConfig {
  fooVar = "Hello World"
}

2.  Load your new config via the FooGrailsPlugin.groovy file.  This code is a modified version of the code found in Spring-Security-Core plugin.  Thanks Burt.
def doWithSpring = {
  mergeConfig(application)
}
private void mergeConfig(GrailsApplication app) {
  ConfigObject currentConfig = app.config.grails.fooConfig
  ConfigSlurper slurper = new ConfigSlurper(Environment.getCurrent().getName());
  ConfigObject secondaryConfig = slurper.parse(app.classLoader.loadClass("FooConfig"))

  ConfigObject config = new ConfigObject();
  config.putAll(secondaryConfig.fooConfig.merge(currentConfig))

  app.config.grails.fooConfig = config;
}

3.  Finally, we need to make our plugin config reload when a config is changed elsewhere in the application.
def onConfigChange = { event ->
  this.mergeConfig(application)
}

Thats it. Thats all I had to do. Now I can use default configs within my plugin and allow my plugin consumers to customize. Fun Stuff.

Here is an example of customization...
grails.fooConfig.fooVar = "I've been updated!"

Full Disclosure : I havent tested this in a deployed WAR yet.
Works from run-war.

Referenced Links
Post 1
Post 2