Utilizing Reusable Code through ColdBox Modules
Follow Along:
Utah
Ortus Solutions
Prolific Module Author
1 wife, 3 kids
Type 1 Diabetic
/**
* Returns the character at a certain position in a string.
*
* @param str String to be checked.
* @param pos Position to get character from.
* @return Returns a character.
* @author Raymond Camden (ray@camdenfamily.com)
* @version 1, December 3, 2001
*/
function CharAt(str,pos) {
return Mid(str,pos,1);
}
box.json
box.json
box.json
{
"name":"cbyaml",
"version":"1.0.1",
"author":"Eric Peterson",
"location":"elpete/cbyaml#v1.0.1",
"homepage":"https://github.com/elpete/cbyaml",
"documentation":"https://github.com/elpete/cbyaml",
"repository":{
"type":"git",
"URL":"https://github.com/elpete/cbyaml"
},
"bugs":"https://github.com/elpete/cbyaml/issues",
"slug":"cbyaml",
"shortDescription":"Provides easy serialization and deserialization of yaml files",
"description":"Provides easy serialization and deserialization of yaml files",
"type":"modules",
"dependencies":{
"cbjavaloader":"^2.0.0+44"
},
"devDependencies":{
"coldbox":"^5.6.2+1021",
"testbox":"^3.0.0"
},
"installPaths":{
"testbox":"testbox/",
"coldbox":"tests/resources/app/coldbox/",
"cbjavaloader":"modules/cbjavaloader/"
},
"scripts":{
"postVersion":"package set location='elpete/cbyaml#v`package version`'"
},
"ignore":[
"**/.*",
"test",
"tests"
]
}
Discover the full schema at https://commandbox.ortusbooks.com/package-management/box.json
Not using ColdBox yet? Check out this guide to starting one piece at a time:
Self-contained ColdBox Applications
ModuleConfig.cfc
ModuleConfig.cfc
ModuleConfig.cfc
Property | Purpose |
---|---|
name | The unique name of the module |
entryPoint | The default route into this module (i.e. /api/v1) |
cfmapping | The mapping to access this module |
dependencies | Other modules that must be loaded before this module |
autoMapModels | Set to true to have WireBox automatically map your models folder |
Find all the properties at
https://coldbox.ortusbooks.com/hmvc/modules/moduleconfig/public-module-properties-directives
ModuleConfig.cfc
Method | Purpose |
---|---|
configure() | Only interact with this module. Use onLoad() for cross-module, cross-framework dependencies. |
onLoad() | When you need the framework loaded first. |
onUnload() | Undo what you did in load. |
ModuleConfig.cfc
this.autoMapModels = true;
/*
Automatically maps all of your models to
{modelName}@{moduleName}
property name="builder" inject="Builder@qb";
*/
ModuleConfig.cfc
function configure() {
binder.map( "DefaultGrammar" )
.to( "#moduleMapping#.models.grammars.MySQLGrammar" );
}
Moduleconfig.cfc
is also an Interceptor
component {
this.name = "JSONToRC";
this.author = "Eric Peterson";
this.description = "Add the HTTP Request Body to the RC on each request";
this.version = "1.0.0";
function configure() {}
function preProcess( event, interceptData, buffer, rc, prc ) {
var jsonContent = event.getHTTPContent( json = true );
if ( isStruct( jsonContent ) ) {
structAppend( rc, jsonContent );
}
}
}
redirectBack
redirectBack
Usage
component {
property name="auth" inject="AuthenticationService@cbauth";
property name="flash" inject="coldbox:flash";
function new( event, rc, prc ){
param prc.errors = flash.get( "registration_form_errors", {} );
event.setView( "registrations/new" );
}
function create( event, rc, prc ){
var result = validateModel(
target = rc,
constraints = {
"email" : {
"required" : true,
"type" : "email",
"uniqueInDatabase" : { "table" : "users", "column" : "email" }
},
"password" : { "required" : true },
"passwordConfirmation" : { "required" : true, "sameAs" : "password" }
}
);
if ( result.hasErrors() ) {
flash.put( "registration_form_errors", result.getAllErrorsAsStruct() );
redirectBack();
return;
}
var user = getInstance( "User" ).create( { "email" : rc.email, "password" : rc.password } );
auth.login( user );
relocate( uri = "/" );
}
}
redirectBack
Directory Structure
redirectBack
box.json
{
"name": "redirectBack",
"version": "1.0.4",
"location": "elpete/redirectBack#v1.0.4",
"slug": "redirectBack",
"shortDescription":
"Caches the last request in the flash scope to give easy redirects back",
"type": "modules",
"scripts": {
"postVersion": "package set location='elpete/redirectBack#v`package version`'",
"onRelease": "publish",
"postPublish": "!git push && git push --tags"
},
"ignore": [
"**/.*",
"test",
"tests"
]
}
redirectBack
ModuleConfig.cfc
this.title = "redirectBack";
this.author = "Eric Peterson";
this.webURL = "https://github.com/elpete/redirectBack";
this.description = "Caches the last request in the flash scope to give easy redirects back";
this.version = "1.0.4";
Properties
redirectBack
ModuleConfig.cfc
function configure() {
/*
* can override any of these settings in your `config/ColdBox.cfc` file.
* `moduleSettings = { redirectBack = { key = "overridden_key" } };`
* Or in CommandBox * `config set modules.redirectBack.key="overridden_key"`
*/
settings = {
"key" = "last_url"
};
interceptors = [
{
class = "#moduleMapping#/interceptors/RedirectBack",
name = "RedirectBack",
properties = {}
}
];
}
configure()
redirectBack
ModuleConfig.cfc
/*
* We use onLoad instead of configure here
* because we want to interact with other
* ColdBox settings, such as application helpers.
*/
function onLoad() {
var helpers = controller.getSetting( "applicationHelper" );
arrayAppend( helpers, "#moduleMapping#/helpers/RedirectBackHelpers.cfm" );
controller.setSetting( "applicationHelper", helpers );
}
onLoad()
redirectBack
ModuleConfig.cfc
function onUnload() {
controller.setSetting(
"applicationHelper",
arrayFilter( controller.getSetting( "applicationHelper" ), function( helper ) {
return helper != "#moduleMapping#/helpers/RedirectBackHelpers.cfm";
} )
);
}
onUnload()
redirectBack
interceptors/RedirectBack.cfc
component extends="coldbox.system.Interceptor" {
property name="moduleSettings" inject="coldbox:moduleSettings:redirectBack";
function postProcess( event, interceptData, buffer, rc, prc ) {
var flash = wirebox.getInstance( dsl = "coldbox:flash" );
if ( ! event.isAjax() ) {
flash.put(
name = moduleSettings.key,
value = event.isSES() ? event.getCurrentRoutedUrl() : event.getCurrentEvent(),
autoPurge = false
);
}
}
}
redirectBack
RedirectBackHelpers.cfm
function redirectBack() {
var moduleSettings = wirebox.getInstance( dsl = "coldbox:moduleSettings:redirectBack" );
var flash = wirebox.getInstance( dsl = "coldbox:flash" );
arguments.event = flash.get( moduleSettings.key, "" );
relocate( argumentCollection = arguments );
}
cbyaml
Pros
Cons
Can be private (Private Repos)
Pros
Cons
Easy to iterate on and develop
Great for internal API versions
component extends="testbox.system.BaseSpec" {
function beforeAll() {
include "/root/functions/normalizeToArray.cfm";
}
function run() {
describe( "normalizeToArray", function() {
it( "returns an array unmodified", function() {
var actual = normalizeToArray( [ 1, 2, 3, 4 ] );
expect( actual ).toBe( [ 1, 2, 3, 4 ] );
} );
it( "converts a list to an array", function() {
var actual = normalizeToArray( "1,2,3,4" );
expect( actual ).toBe( [ 1, 2, 3, 4 ] );
} );
} );
}
}
component extends="tests.resources.ModuleIntegrationSpec" appMapping="/app" {
variables.travisYmlSamplePath = expandPath(
"/tests/resources/sample-files/.travis.sample.yml"
);
function run() {
describe( "Yaml Parser", function() {
it( "can deserialize yaml strings", function() {
var parser = getWireBox().getInstance( "Parser@cbyaml" );
var travisYmlSample = fileRead( variables.travisYmlSamplePath );
var actual = parser.deserialize( travisYmlSample );
expect( actual ).toBe( getTravisYmlAsCF() );
} );
} );
}
function getTravisYmlAsCF() { /* ... */ }
}
coldbox create app
install cb-module-template
module scaffold my-awesome-module "It will blow your mind!"
@_elpete
elpete
dev.elpete.com