You can control how CommandBox loads your module by setting optional settings in the this scope.
this.autoMapModels - Will automatically map all model objects under the models folder in WireBox using @modulename as part of the alias.
this.modelNamespace - The name of the namespace to use when registering models in WireBox. Defaults to name of the module.
this.cfmapping - The CF mapping that will be registered for you that points to the root of the module. Defaults to name of the module.
this.disabled - You can manually disable a module from loading and registering.
this.dependencies - An array of dependent module names. All dependencies will be registered and activated FIRST before the module declaring them
component{
// Module Properties
this.autoMapModels = true;
this.modelNamespace = "test";
this.cfmapping = "test";
this.dependencies = [ "otherModule", "coolModule" ];
function configure(){}
}The configuration for a module is contained within in the ModuleConfig.cfc that lives in the root folder. Here's an overview of the options for configuring your module.
component{
// Module Properties
this.autoMapModels = true;
this.modelNamespace = "test";
this.cfmapping = "test";
this.dependencies = [ "otherModule", "coolModule" ];
function configure(){
// Settings for my module
settings = {
mySetting = 'isCool',
settingsCanBe = [
'complex',
'values'
]
};
// Declare some interceptors to listen
interceptors = [
{
class='#moduleMapping#.interceptors.TestInterceptor'
}
];
// Ad-hoc interception events I will announce myself
interceptorSettings = {
customInterceptionPoints = ''
};
// Manually map some models
binder.map( 'foo' ).to( '#moduleMapping#.com.foo.bar' );
}
// Runs when module is loaded
function onLoad(){
log.info('Module loaded successfully.' );
}
// Runs when module is unloaded
function onUnLoad(){
log.info('Module unloaded successfully.' );
}
// An interceptor that listens for every command that's run.
function preCommand( interceptData ){
// I just intercepted ALL Commands in the CLI
log.info('The command executed is #interceptData.CommandInfo.commandString#');
}
}Every module follows a sequence of steps when it is loaded and unloaded. Modules are automatically loaded for you when CommandBox starts up, but here are some ways for a module to affect how it loads.
There are two life-cycle callback events you can declare in your ModuleConfig.cfc:
onLoad() - Called when the module is loaded and activated
onUnLoad() - Called when the module is unloaded from memory
This gives you great hooks for you to do bootup and shutdown procedures for this specific module.
function onLoad(){
log.info('Module loaded successfully.' );
}
function onUnLoad(){
log.info('Module unloaded successfully.' );
}The ModuleConfig.cfc object itself is an interceptor so you can declare all of the CLI's interception points in the configuration object and they will be registered as interceptors.
function preCommand( interceptData ){
// I just intercepted ALL Commands in the CLI
log.info('The command executed is #interceptData.CommandInfo.commandString#');
}The configure() method will be run before a module is loaded.
The following variables will be created for you in the variables scope of the ModuleConfig.cfc.
shell - The shell object (kind of the core CommandBox controller)
moduleMapping - The component mapping to the module
modulePath - The physical path to the module
logBox - The LogBox instance
log - A named logger, ready to log!
wirebox - Your friendly neighborhood DI engine
binder - The WireBox binder, handy for mapping models manually
The configure() method does not accept or return any data. Instead, the config CFC itself represents the data for configuring the module with data structures in the variables scope. It's the job of the configure method to ensure that these data structures are created and populated.
There is no required data, but here is the list of optional data you can set:
settings - A struct of custom module settings. These defaults can be overridden when the module is loaded with the CommandBox user config.
interceptors - An array of declared interceptor structures that should be loaded in the entire application. Each interceptor structure contains class, and optional properties.
interceptorSettings - A structure of settings for interceptor interactivity which includes the sub-key customInterceptionPoints, a list of custom interception points to add to the application wide interceptor service
Here is an example configure() method. Note these data structures are placed in the variables scope.
component{
function configure(){
// Settings for my module
settings = {
mySetting = 'isCool',
settingsCanBe = [
'complex',
'values'
],
andEven = {
nested = {
any = 'way'
},
you = 'like'
}
};
// Declare some interceptors to listen
interceptors = [
{
class='#moduleMapping#.interceptors.TestInterceptor'
},
{
class='#moduleMapping#.interceptors.DoCoolThings',
properties={
coolnessFactor='max',
crankItToEleven=true
}
}
];
// Ad-hoc interception events I will announce myself
interceptorSettings = {
customInterceptionPoints = 'launchInitiated,velocityAcheived,singularityAcquired'
};
// Manually map some models
binder.map( 'foo' ).to( '#moduleMapping#.com.foo.bar' );
}
}