Module error: DEFAULTLAYOUT is undefined

Hi I'm getting an error loading modules (which used to work fine). To
check it wasn't anything I'd done, I used the ColdBox Builder plugin
to create a new module in my app and I still get:

An unhandled exception has occurred. Please look at the diagnostic
information below:
Type Expression
Message Element DEFAULTLAYOUT is undefined in a CFML structure
referenced as part of an expression.
Detail
Extended Info
Tag Context C:\xampp\htdocs\testapp\frameworks\coldbox-core\system\web
\context\RequestContext.cfc (223)
C:\xampp\htdocs\testapp\modules\foobar\handlers\Home.cfc (7)
C:\xampp\htdocs\testapp\frameworks\coldbox-core\system\web
\Controller.cfc (651)
C:\xampp\htdocs\testapp\frameworks\coldbox-core\system\web
\Controller.cfc (542)
C:\xampp\htdocs\testapp\frameworks\coldbox-core\system\Coldbox.cfc
(226)
C:\xampp\htdocs\testapp\Application.cfc (103)

I've got my application set up to use composition instead of
Application.cfc extending ColdBox.cfc. I got ColdBox directly from
github.

The config for the Module is (as generated):

<cfcomponent output="false" hint="My Module Configuration">
<cfscript>
/**
Module Directives as public properties
this.title = "Title of the module";
this.author = "Author of the module";
this.webURL = "Web URL for docs purposes";
this.description = "Module description";
this.version = "Module Version"

Optional Properties
this.viewParentLookup = (true) [boolean] (Optional) // If true,
checks for views in the parent first, then it the module.If false,
then modules first, then parent.
this.layoutParentLookup = (true) [boolean] (Optional) // If true,
checks for layouts in the parent first, then it the module.If false,
then modules first, then parent.
this.entryPoint = "" (Optional) // If set, this is the default
event (ex:forgebox:manager.index) or default route (/forgebox) the
framework
                         will use to create an entry link to the module.
Similar to a default event.

structures to create for configuration
- parentSettings : struct (will append and override parent)
- settings : struct
- datasources : struct (will append and override parent)
- webservices : struct (will append and override parent)
- interceptorSettings : struct of the following keys ATM
  - customInterceptionPoints : string list of custom interception
points
- interceptors : array
- routes : array Allowed keys are same as the addRoute() method of the
SES interceptor.
- modelMappings : structure of model mappings. Allowed keys are the
alias and path, same as normal model mappings.

Available objects in variable scope
- controller
- appMapping (application mapping)
- moduleMapping (include,cf path)
- modulePath (absolute path)
- log (A pre-configured logBox logger object for this object)

Required Methods
- configure() : The method ColdBox calls to configure the module.

Optional Methods
- onLoad() : If found, it is fired once the module is fully loaded
- onUnload() : If found, it is fired once the module is unloaded

*/

  // Module Properties
  this.title = "foo";
  this.author = "foo";
  this.webURL = "http://";
  this.description = "testing module error";
  this.version = "1.0";
  // If true, looks for views in the parent first, if not found, then
in the module. Else vice-versa
  this.viewParentLookup = true;
  // If true, looks for layouts in the parent first, if not found, then
in module. Else vice-versa
  this.layoutParentLookup = true;
  // Module Entry Point
  this.entryPoint = "foobar:home.index";

  function configure(){

    // parent settings
    parentSettings = {

    };

    // module settings - stored in modules.name.settings
    settings = {

    };

    // datasources
    datasources = {

    };

    // web services
    webservices = {

    };

    // SES Routes
    routes = [
      //{pattern="/api-docs", handler="api",action="index"}
    ];

    // Custom Declared Points
    interceptorSettings = {
      customInterceptionPoints = ""
    };

    // Custom Declared Interceptors
    interceptors = [
    ];

  }

  /**
  * Fired when the module is registered and activated.
  */
  function onLoad(){

  }

  /**
  * Fired when the module is unregistered and unloaded
  */
  function onUnload(){

  }

</cfscript>
</cfcomponent>

The parent application runs fine, any thoughts appreciated.

Thanks,

- John

Make that 2 of us I just downloaded the latest from git to find this problem
as well.

Regards,
Andrew Scott
http://www.andyscott.id.au/

From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com] On
Behalf Of John Whish
Sent: Monday, 20 September 2010 6:21 PM
To: ColdBox Platform
Subject: [coldbox:5814] Module error: DEFAULTLAYOUT is undefined

Hi I'm getting an error loading modules (which used to work fine). To

check it

wasn't anything I'd done, I used the ColdBox Builder plugin to create a

new

module in my app and I still get:

An unhandled exception has occurred. Please look at the diagnostic
information below:
Type Expression
Message Element DEFAULTLAYOUT is undefined in a CFML structure
referenced as part of an expression.
Detail
Extended Info
Tag Context C:\xampp\htdocs\testapp\frameworks\coldbox-
core\system\web
\context\RequestContext.cfc (223)
C:\xampp\htdocs\testapp\modules\foobar\handlers\Home.cfc (7)
C:\xampp\htdocs\testapp\frameworks\coldbox-core\system\web
\Controller.cfc (651)
C:\xampp\htdocs\testapp\frameworks\coldbox-core\system\web
\Controller.cfc (542)
C:\xampp\htdocs\testapp\frameworks\coldbox-core\system\Coldbox.cfc
(226)
C:\xampp\htdocs\testapp\Application.cfc (103)

I've got my application set up to use composition instead of

Application.cfc

extending ColdBox.cfc. I got ColdBox directly from github.

The config for the Module is (as generated):

<cfcomponent output="false" hint="My Module Configuration"> <cfscript>
/**
Module Directives as public properties
this.title = "Title of the module";
this.author = "Author of the module";
this.webURL = "Web URL for docs purposes";
this.description = "Module description";
this.version = "Module Version"

Optional Properties
this.viewParentLookup = (true) [boolean] (Optional) // If true,
checks for views in the parent first, then it the module.If false, then

modules

first, then parent.
this.layoutParentLookup = (true) [boolean] (Optional) // If true, checks

for

layouts in the parent first, then it the module.If false, then modules

first,

then parent.
this.entryPoint = "" (Optional) // If set, this is the

default

event (ex:forgebox:manager.index) or default route (/forgebox) the
framework

will use to create an entry link to the module.
Similar to a default event.

structures to create for configuration
- parentSettings : struct (will append and override parent)
- settings : struct
- datasources : struct (will append and override parent)
- webservices : struct (will append and override parent)
- interceptorSettings : struct of the following keys ATM
  - customInterceptionPoints : string list of custom interception

points

- interceptors : array
- routes : array Allowed keys are same as the addRoute() method of the SES
interceptor.
- modelMappings : structure of model mappings. Allowed keys are the alias
and path, same as normal model mappings.

Available objects in variable scope
- controller
- appMapping (application mapping)
- moduleMapping (include,cf path)
- modulePath (absolute path)
- log (A pre-configured logBox logger object for this object)

Required Methods
- configure() : The method ColdBox calls to configure the module.

Optional Methods
- onLoad() : If found, it is fired once the module is fully

loaded

- onUnload() : If found, it is fired once the module is unloaded

*/

  // Module Properties
  this.title = "foo";
  this.author = "foo";
  this.webURL = "http://";
  this.description = "testing module error";
  this.version = "1.0";
  // If true, looks for views in the parent first, if not found, then

in the

module. Else vice-versa
  this.viewParentLookup = true;
  // If true, looks for layouts in the parent first, if not found,

then in

I’ve done some digging and changed the code on system\web\context\RequestContext.cfc (223) to:

if( len(cModule) AND len(instance.modules[cModule].defaultLayout) ){
setValue(“currentLayout”, instance.modules[getCurrentModule()].layoutSettings.defaultLayout,true);
}

to:

if (StructKeyExists(instance.modules[cModule], “defaultLayout”)){
if( len(cModule) AND len(instance.modules[cModule].defaultLayout) ){
setValue(“currentLayout”, instance.modules[getCurrentModule()].layoutSettings.defaultLayout,true);
}
}

The module now loads, but I’ve not tested further, can you try Andrew?

Thanks,

  • John

Oops, sorry, Module layouts work, but that change breaks parent app.

This seems to work:

if( len(cModule) AND StructKeyExists(instance.modules[cModule], “defaultLayout”) AND len(instance.modules[cModule].defaultLayout) ){
setValue(“currentLayout”, instance.modules[getCurrentModule()].layoutSettings.defaultLayout,true);
}

I ended up just removing those lines.

Regards,

Andrew Scott

http://www.andyscott.id.au/

That would do it :slight_smile:

After step debugging what is happening, I’ve figured out what that code is for, it should be:

if( len(cModule) AND len(instance.modules[cModule].layoutSettings.defaultLayout) ){
setValue(“currentLayout”, instance.modules[getCurrentModule()].layoutSettings.defaultLayout,true);
}

Then what you can set the layout name inside the ModuleConfic.cfc configure method:

layoutSettings = {
defaultLayout = “layout.mymodule.cfm”
};

Pretty handy if you keep module layouts inside the parent app layouts folder.

  • John

I might be missing something, but this doesn’t use the module setting this.layoutParentLookup, which means it will always use the module layout.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Yes, you’re right Andrew. To me, it makes sense that if you configure a layout inside a module’s config, that it should check the layout folder of the module first before looking in the parent. Although I do agree that this is confusing if it conflicts with the this.layoutParentLookup setting.

Typo on my part.

Fixed, but this is so you can declare a defaultLayout at the module level, so you don’t have to be setting one (if using one) on every request for a module.

Luis F. Majano
President
Ortus Solutions, Corp

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