ContentBox Module Custom Layout

I am building a new application. My strategy is to build the entire admin interface as a contentbox module.

However I am having trouble when it comes to layouts. I want to either have a completely separate layout from the admin layout or a sub layout wrapped in the admin layout.

I tried adding the following to moduleconfig.cfc but contentbox ignored it:
layoutSettings = {
defaultLayout = “layouts/custom.cfm”
};

Is there any way to achieve this?

Also one side question, I know you offer themes for the frontend but are there plans to offer admin themeing capabilities?

Thanks!

This may help

http://www.andyscott.id.au/blog/extending-contentbox-with-modules-separate-to-contentbox-part-ii

And yes to your side question… Luis can jump in with the details.

Thanks Andrew. I actually had just followed through your 2 blog posts before posting this. However I read over the one you referenced again and here is what I tried:

I added the following to configure() in the moduleconfig file:
layouts = [
{ name = “wizard”,
file = “wizard.cfm”,
folders = “^layouts,layouts”
},
{ name = “main”,
file = “Main.cfm”,
folders = “^layouts,layouts”
}
];

I then added the following to my parent handler that extends all sub handlers:

public void function preProcess(event, interceptData) eventPattern="^(contentbox-ui|mymodule)" {
super.preProcess(event, interceptData);
event.setLayout(name=“wizard”, module=“WebPanel”);
}

I didn’t get any errors or any indication that it did anything.

Can you tell me what I did wrong?

Thanks!

Not sure where you got the layouts = [] from but that is not a standard moduleConfig setting.

Actually I have now resorted to searching through google to find any examples of this from blogs to github, etc. The only example I found is in your example and I can’t get it to work. I did finally get errors to come through btw:

I simplified my handler while I’m testing down to just the following:

component extends=“contentbox-ui.interceptors.CBRequest” singleton {
public void function preProcess(event, interceptData) eventPattern="^(contentbox-ui|WebPanel)" { }
}

And I get the following error:

Application Execution ExceptionError Type: Builder.BuildCFCDependencyException : [N/A]

Error Messages: Error building: modules.contentbox.modules.WebPanel.handlers.Home -> The PROPERTIES parameter to the init function is required but was not passed in. with constructor arguments: {controller={[(Component=coldbox.system.web.Controller)]}}… etc, etc, etc…

Thoughts? Working examples?

Looks like a DI not working…

Also the posts I provided show how to use modules in ContentBox that are not stored in the normal ContentBox location. Otherwise a module should just work.

I do have another few posts on modules in ContentBox, which should get you going. But it sounds like you have issues with your own code at the moment.

But it looks like you are trying to inject something into your handler that also requires an init argument. Have you nided this in the ModuleConfig or just DI’ed into the property, it looks like just the property.

Not sure what you mean by “nided this in the ModuleConfig”?

Tim,

Are you trying to register an interception point or create a handler?

signature0.jpg

Luis F. Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Social: twitter.com/lmajano facebook.com/lmajano

From what andrew explained, I think both.

signature0.jpg

This is your handler

modules.contentbox.modules.WebPanel.handlers.Home

This is where the error is occurring, in that file you have a DI’ed or Dpendency Injected object, that is requiring an init argument. Try reducing your handler down to bare bones and try again.

signature0.jpg

Here is my Home.cfc handler:

component extends=“contentbox-ui.interceptors.CBRequest” singleton {

public void function preProcess(event, interceptData) eventPattern="^(contentbox-ui|WebPanel)" { }
}

Pretty bare bones. Same error.

Also here is a complete copy of my moduleConfig.cfc:
component hint=“Web Panel Configuration” {

this.title = “WebPanel”;
this.author = “Custom”;
this.webURL = “Test”;
this.description = “This is an awesome webpanel module”;
this.version = “1.0”;
this.viewParentLookup = true;
this.layoutParentLookup = true;
this.entryPoint = “WebPanel”;

function configure(){

routes = [
{pattern="/", handler=“home”,action=“index”},
{pattern="/:handler/:action?"}
];

interceptorSettings = {
customInterceptionPoints = “”
};

interceptors = [
];
}

function onLoad(){
var menuService = controller.getWireBox().getInstance(“AdminMenuService@cb”);
menuService.addSubMenu(topMenu=menuService.MODULES,name=“WebPanel”,label=“Web Panel”,href="#menuService.buildModuleLink(‘WebPanel’,‘home’)#");
}

function onActivate(){

}
function onUnload(){
var menuService = controller.getWireBox().getInstance(“AdminMenuService@cb”);
menuService.removeSubMenu(topMenu=menuService.MODULES,name=“WebPanel”);
}
function onDeactivate(){}
}

signature0.jpg

Ok Tim, I see what your issue is…

This is an interceptor and not a handler

component extends=“contentbox-ui.interceptors.CBRequest” singleton {

public void function preProcess(event, interceptData) eventPattern="^(contentbox-ui|WebPanel)" { }
}

signature0.jpg

Okay, I guess I need to read more about interceptors/wirebox/aop/di/etc. Looks like you really can’t get far with coldbox without a deep knowledge of these things.

Thanks for helping me get that sorted.

signature0.jpg

It isn’t hard to understand…

Handlers are what ColdBox calls controllers, interceptors are specific objects usually stored in a folder called interceptors.

Here are more blogs on interceptors

http://www.andyscott.id.au/blog/a-funky-way-to-replacing-captcha-in-contentbox

http://www.andyscott.id.au/blog/adding-multiple-pages-to-contentbox-blog-posts

http://www.andyscott.id.au/blog/adding-interceptors-to-your-contentbox-themes

http://www.andyscott.id.au/blog/using-interceptors-in-coldbox-for-greater-scalabaility

http://www.andyscott.id.au/blog/contentbox-media-manager-and-uploading-images-of-different-sizes

There is more on my blog just go to the search on the right side and type in interceptors.

ContentBox has a full range of different interception points, to create an interceptor you can just create a file in the interceptors folder and add that snippet you had earlier. Then all you need to do, is then in your moduleConfig is to then add the interceptor, something along the lines of

// Custom Declared Interceptors
interceptors = [
{class="#moduleMapping#.interceptors.moduleInterceptor", properties = { entryPoint=this.entryPoint }, name=“moduleInterceptor@cronus” }
];

Then when the module is loaded, it will setup the interceptor ready to be called. All you need to do is create a file with that interceptor code and re-init the framework or go to the dashboard and reload the application from there. Then any time that point is announced the new module interceptor is then called.

For more on the points, you can find them in the ModuleConfig of ContentBox, ContentBox-UI etc.

Creating the interceptor is the easy bit, understanding what you want to achieve from it is the hard bit.

signature0.jpg

Ahh, okay, thanks for the rundown, I’ll certainly refer to those resources. Here is what I have done that should work right?

You’ll notice I put an abort statement in the interceptor, that is so I can tell if it is running which its not.

Here’s what I did:

Added an interceptor called /modules/contentbox/modules/WebPanel/model/interceptors/layout.cfc, with the following:
component extends=“contentbox-ui.interceptors.CBRequest” singleton
{

public void function preProcess(event, interceptData) eventPattern="^(contentbox-ui|WebPanel)"
{
abort;
super.preProcess(event, interceptData);
event.setLayout(name=“wizard”, module=“WebPanel”);
}

}

Added the following to /modules/contentbox/modules/WebPanel/ModuleConfig.cfc:
// Custom Declared Interceptors
interceptors = [
{
class=“contentbox.modules.WebPanel.model.interceptors.layout”,
properites = {
varName = “LayoutInterceptor”
}
}
];

signature0.jpg

ok did you reload the application from the cbadmin dashboard?

signature0.jpg

Also depends on whether you are starting ColdFusion from the command line or not, but you may want to look into logging with ColdBox and logging to a file.

When you switch that on, you could add this to your interceptor

component extends=“contentbox-ui.interceptors.CBRequest” singleton {

property name=“log” inject=“logbox:logger:{this}”;

public void function preProcess(event, interceptData) eventPattern="^(contentbox-ui|WebPanel)" {

super.preProcess(event, interceptData);
event.setLayout(name=“wizard”, module=“WebPanel”);
log.info(“setting layout to Wizard from module webpanel…”);
}

}

Then the info will appear in your log files. It is the best way to see if an interceptor is firing.

signature0.jpg

Yep. Just restarted the coldfusion service too just to make sure. Same thing.

Also I start Coldfusion from the services manager. I will go ahead and get the logging setup if its not already but shouldn’t the abort statement alone be able to tell me if the preProcess is running?

signature0.jpg

Yep, its the eventPattern. Once I removed it the abort command fired confirming that it works. However I just wanted it to run for my module but the following eventPattern isn’t working: eventPattern="^WebPanel:"

Is your module firing standalone or as part of ContentBox admin?