Now, let's say you want to override the layout for a module. Go to the host application's layouts folder and create a folder called modules
and then a folder according to the module name, in our case simpleModule
:
What this does, is create the override structure that you need. So now, you can map 1-1 directly from this overrides folder to the module's layouts folder. So whatever layout you place here that matches 1-1 to the module, the parent will take precedence. Now remember this is because our layouParentLookup property is set to true. If we disable it or set it to false, then the module takes precedence first. If not found in the module, then it goes to the parent or host application and tries to locate the layout. That's it, so if I place a main.cfm layout in my parent structure, the that one will take precedence.
These features are great for skinning modules or just overriding view capabilities a-la-carte. So please take note of them as it is very powerful.
You can also explicitly render layouts or views directly from a module via the Renderer plugin's renderLayout()
and renderView()
methods. These methods now can take an extra argument called module.
renderLayout(layout, view, module)
renderView(view, cache, cacheTimeout,cacheLastAccessTimeout,cacheSuffix, module)
So you can easily pinpoint renderings if needed.
Caution Please note that whenever these methods are called, the override algorithms ALSO are in effect. So please refer back to the view and layout parent lookup properties in your modules' configuration.
You can also implicitly setup a default layout to use when rendering views from the specific module. This only works when you call the event.setView()
method from your module event handlers. Once called, the framework will discover the default layout to render that view in. You set up the default layout for a module by using the layoutSettings structure in your configuration:
Caution The set default layout MUST exist in the layouts folder of your module and the declaration must have the
.cfm
extension attached.
This tells the framework to render the simple/index.cfm
view in the module simpleModule
. However, let's override the view first. Go to the host application's views folder and create a folder called modules
and then a folder according to the module name, in our case simpleModule
:
What this does, is create the override structure that you need. So now, you can map 1-1 directly from this overrides folder to the module's views folder. So whatever view you place here that matches 1-1 to the module, the parent will take precedence. Now remember this is because our viewParentLookup
property is set to true. If we disable it or set it to false, then the module takes precedence first. If not found in the module, then it goes to the parent or host application and tries to locate the view. That's it, so if I place a simple/index.cfm
view in my parent structure, the that one will take precedence.
The ColdBox rendering engine has been adapted to support module renderings and also to support multiple discovery algorithms when rendering module layouts and views. When you declare a module you can declare two of its public properties to determine how rendering overrides occur. These properties are:
The default order of overrides ColdBox offers is both viewParentLookup & layoutParentLookup
to true. This means that if the layout or view requested to be rendered by a module exists in the overrides section of the host application, then the host application's layout or view will be rendered instead. Let's investigate the order of discover:
viewParentLookup = true
Host override module specific (e.g. {HOST}/views/modules/myModule/myView.cfm)
Host override common (e.g. {HOST}/views/modules/myView.cfm)
Module view (e.g. /modules/myModule/views/myView.cfm)
Default view discovery from host (e.g. {HOST}/views/myView.cfm)
viewParentLookup = false
Module view (e.g. /modules/myModule/views/myView.cfm)
Host override module specific (e.g. {HOST}/views/modules/myModule/myView.cfm)
Host override common (e.g. {HOST}/views/modules/myView.cfm)
Default view discovery from host (e.g. {HOST}/views/myView.cfm)
layoutParentLookup = true
Host override module specific (e.g. {HOST}/layouts/modules/myModule/myLayout.cfm)
Host override common (e.g. {HOST}/layouts/modules/myLayout.cfm)
Module layout (e.g. /modules/myModule/layouts/myLayout.cfm)
Default layout discovery from host (e.g. {HOST}/layouts/Default.cfm)
layoutParentLookup = false 1. Module layout (e.g. /modules/myModule/layouts/myLayouts.cfm)
2. Host override module specific (e.g. {HOST}/layouts/modules/myModule/myLayout.cfm)
3. Host override common (e.g. {HOST}/layouts/modules/myLayout.cfm)
4. Default layout discovery from host (e.g. {HOST}/layouts/Default.cfm)
Let's do some real examples, I am building a simple module with 1 layout and 1 view. Here is my directory structure for them:
Now, in my handler code I just want to render the view by using our typical event.setView()
method calls or implicit views.
Property
Type
Required
Default
Description
viewParentLookup
boolean
false
true
If true, coldbox checks for views in the parent overrides first, then in the module. If false, coldbox checks for views in the module first, then the parent.
layoutParentLookup
boolean
false
true
If true, coldbox checks for layouts in the parent overrides first, then in the module. If false, coldbox checks for layouts in the module first, then the parent.