(Quick Reference)

3 Configuration API - Reference Documentation

Authors: Marc Palmer (marc@grailsrocks.com), St├ęphane Maldini (smaldini@vmware.com)

Version: 1.0.RC3

3 Configuration API

The Configuration API adds the following features:
  • A way to declare the Config properties that a plugin supports
  • Automatic namespacing of plugin Config values to avoid clashes
  • Validation of Config values
  • Merging of config from plugins into main Application config
  • The ability for plugins to configure other plugins
  • An injected "pluginConfig" variable in all artefacts containing the plugin's configuration
  • Automatic merging of legacy Config settings into the new plugin namespace

All of this adds up to more powerful integration and less frustration and confusion for developers.

3.1 Changing Application and Plugin Config Values

To change application or plugin configuration from within a plugin you need to declare the doWithConfig hook in your plugin descriptor.

The code uses a simple DSL that is identical to normal Config except:

  1. The top level nodes are plugin names or "application" to determine what scope of config you are changing
  2. The closure is passed the existing config as its first and only argument

The application Config is loaded first. All the doWithConfig blocks are evaluated and the results merged in.

def doWithConfig = { config ->
    platformUi {
        ui.Bootstrap.button.cssClass = 'btn'
        ui.Bootstrap.tab.cssClass = 'tab-pane'
        ui.Bootstrap.field.cssClass = 'input'
    }
    
    application {
        // set something based on another config value that has already been
        // by the application
        grails.x.y = config.p.q == 'something' ? true : false
    }
}

See doWithConfig for more details.

3.2 Declaring Configuration Options

To make use of the plugin configuration features and make life easier for developers, your plugin must define the configuration options it accepts.

This allows the platform to warn users when they mistype a config name or supply and invalid value - and to formalise definition of default values rather than a plugin merging in default values.

Do declare the options your plugin supports, add the doWithConfigOptions closure to your plugin descriptor:

def doWithConfigOptions = {
    'organization.name'(type: String, defaultValue: 'My Corp (set plugin.platformCore.organization.name)')
    'site.name'(type: String, defaultValue: 'Our App (set plugin.platformCore.site.name)')
}

This block, from the platform core, defines two configuration values of type String, with a default value.

You can also supply a custom validator:

def doWithConfigOptions = {
    'concurrentConnections'(type: Integer, defaultValue: 10, 
        validator: { v -> v < 500 ? null : 'concurrent.connections.too.big' }
}

Behaving just like constraint validators, your validator returns null for "ok" or an i18n message string for the error.

When implementing this config in your plugins, you may want to use the legacyPrefix value so that applications that use your existing Config settings will continue to work, and users will be warned to update their Config.

See doWithConfigOptions for more details.

3.3 Accessing Plugin Config

Plugins that declare their configuration with doWithConfigOptions can get access to their "slice" of the Config using the pluginConfig variable.

The pluginConfig variable is automatically injected into all artefacts of your plugin, automatically namespace for your plugin using the plugin.<pluginName>. prefix.

So in a service you can trivially access this config inside a service or controller for example:

class MyPluginService {
    def doSomething() {
       if (pluginConfig.enabled) {
          println "It worked!"
       }
    }
}