Modul Layout setting

I tired to get my around the moduls layout settings...

My modul 'admin' has it's own layout "Layout.Admin.cfm".

Thus in ModuleConfig.cfc I set:

this.layoutParentLookup = false;

and added in the methode configure()

layoutSettings = {
      defaultLayout = "Layout.Admin.cfm",
      defaultView = ""
    }

But i never gets fired, instead always the layout from the parent is
used (`Layout.Main.cfm').

How do it set the general layout for a modul?

Daniel

Interesting.. I thought maybe you were missing something, but unless
I am also missing something, the only way I could get the module
layout to trigger properly was to using the following in my ajax
module's handler.. even with the ModuleConfig layout keys setup i was
getting Layout.Main instead...

<cfset event.setView(name="ajax/
test",layout="Layout.Ajax",module="Ajax")/>

Regards,
Adam

Hmm, very interesting.

At this point in time, you cannot declare implicit layout settings for modules, you have to do it programmatically in your module.

What does this mean? Well, you can use the following in your module handlers:

event.setLayout(“name”);
event.setView(name=“view”, layout=“layout”);

I usually have preHandler() or the module configure listenting to preProcess() and selecting the default layout for my module.

ex: Remember that your ModuleConfig.cfc is AN INTERCEPTOR already and registered for you. So I can easily define the following in my module called ‘admin’:

/**

  • @eventPattern ^admin:.*
    */
    function preProcess(){
    // event called to module, set default layout
    event.setLayout(“Layout.ModuleAdmin”);
    }

I have also created a ticket for this, where in the future, you can define implicit layout configurations for modules so developers can be lazy and I like lazy :slight_smile:

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

Thanks folks,

at the moment I stick with the preProcess() example Luis
mentioned....I didn't think about that.. pretty cool!

But I would still vote to define it in the module settings. That seems
to be clearer.

Daniel
www.danielschmid.anme

I’m having the problem where even if I use the preProcess or preHandler() approach my modules are still looking in the host app’s layouts instead of the module’s layouts. Here is what I have in my ModuleConfig.cfc:

this.viewParentLookup = false;
this.layoutParentLookup = false;

function preProcess(){
event.setLayout(“admin:main”);
}

However, I am still getting the missingInclude error:

“Could not find the included template //layouts/admin:main.cfm”

I have tried so many different possible approaches but nothing is working.

-Aaron

Are you trying to use the standard layout convention or the module layout convention.

I am betting that the setLayout() is trying to set a layout that is not defined in the module layouts folder.

At least on the surface this is what it appears to be.

I got it figured out but I have some suggestions to help make the module integration much more consistent and to help remove some unnecessary confusion. At present, some methods require the “admin:” prefix while others require the “admin/” prefix and yet others require the additional “module” parameter and still others (setLayout() and setView()) do not require any prefix or additonal paramter at all. This can be very confusing.

I suggest that:

  1. All of the event and request collection methods within the modules are context aware similar to setLayout() and setView(). For example, all of the following method calls within a module named “admin” would route to the appropriate view, handler or action within the “admin” module:

setView(“product/edit”); - looks for /module/admin/views/product/edit.cfm
setLayout(“layout.main”); - looks for /module/admin/layouts/layout.main.cfm
setNextEvent(“Product/edit”); looks for /module/admin/handlers/Product.cfc and calls the edit() action
overrideEvent(“Product/edit”); looks for /module/admin/handlers/Product.cfc and calls the edit() action
renderView(“viewlets/navigation”); - looks for /module/admin/views/viewlets/navigation.cfm
runEvent(“Viewlet/prepareNavigation”); = looks for /module/admin/handlers/Viewlet.cfc and calls prepareNavigation()
And use event.getModuleRoot() in it’s current implementation.

  1. All of the event and request collection methods have a single unified prefix of either “admin/” or “admin:” in the case where the module is named “admin”. For example:

a)
setView(“admin/product/edit”); - looks for /module/admin/views/product/edit.cfm
setLayout(“admin/layout.main”); - looks for /module/admin/layouts/layout.main.cfm
setNextEvent(“admin/Product/edit”); looks for /module/admin/handlers/Product.cfc and calls the edit() action
overrideEvent(“admin/Product/edit”); looks for /module/admin/handlers/Product.cfc and calls the edit() action
renderView(“admin/viewlets/navigation”); - looks for /module/admin/views/viewlets/navigation.cfm
runEvent(“admin/Viewlet/prepareNavigation”); = looks for /module/admin/handlers/Viewlet.cfc and calls prepareNavigation()
And instead of event.getModuleRoot() one could just have “admin/” in the path and that would map to /module/admin/

OR

b)
setView(“admin:product/edit”); - looks for /module/admin/views/product/edit.cfm
setLayout(“admin:layout.main”); - looks for /module/admin/layouts/layout.main.cfm
setNextEvent(“admin:Product/edit”); looks for /module/admin/handlers/Product.cfc and calls the edit() action
overrideEvent(“admin:Product/edit”); looks for /module/admin/handlers/Product.cfc and calls the edit() action
renderView(“admin:viewlets/navigation”); - looks for /module/admin/views/viewlets/navigation.cfm
runEvent(“admin:Viewlet/prepareNavigation”); = looks for /module/admin/handlers/Viewlet.cfc and calls prepareNavigation()
And instead of event.getModuleRoot() one could just have “admin:” in the path and that would map to /module/admin/

Last night I took my admin app which was a nested app within my main ColdBox site and I converted it into a ColdBox module. It took me about 4 hours to re-factor all the code (some of that time was spent trying to figure out why events or layouts or views were not mapping correctly which was due to using an incorrect prefix for the respective method or for not including the additional “module” parameter, etc.). With a syntax like the one proposed in 2a were in place I nearly could have dropped my entire app into the module folder, created a ModuleConfig.cfc and been on my way.

Luis, I hope these suggestions are helpful. I really like the concept of modules and my “admin” app feels much more integrated with my host app and there is already a slight reduction in duplicate files. Thanks for all your hard work and for continuing to support and share this amazing framework and toolkit!

-Aaron

An additional thought:

In order for suggestion 2a to work, the modulesLocation and the AddModuleRoutes settings would have to act as a per application mapping. For instance:

modulesLocation = ‘/shared/coldbox/modules/’
AND
addModuleRoutes(pattern="",module=“admin”);

would result in a mapping of:

this.mappings[“admin”] = “/shared/coldbox/modules/admin”;

Additional thought on my additional thought: You could also use the entryPoint setting in the ModuleConfig to accomplish this, which I think it already does :stuck_out_tongue:

Does anybody else have any thoughts on these suggestions? Luis, what do you think?

  1. All of the event and request collection methods within the modules are context aware similar to setLayout() and setView(). For example, all of the following method calls within a module named “admin” would route to the appropriate view, handler or action within the “admin” module:

Aaron, unfortunately, you cannot make everything context aware, as there can be use cases where you need to talk to specifc modules or maybe NON modules (the parent). So you cannot make everything context aware.

The runEvent(), overrideEvent(), setNextEvent(), requires the event signature, so in this case it needs the module portion in event syntax. This is the agreement for events, that you use event syntax. You cannot make everything context aware, if you do, you introduce more scenarios where you need it off and then those methods need overrides.

As for the “/” notation, that is view folder notation. So if you are using event syntax you use periods, if you do view/folder syntax that uses “/”. You might say? Why don’t you convert the “.” to “/” automatically? Well, what if my folders have a period in the name. Then this would break.

Now, the setView() and setLayout() do not require a prefix and they are context aware, because of the nature of modules. What is this? Well, you need this in order to activate the parent overrides for views and layouts. So you can easily override ANY view or layout from a parent or vice versa. So you do not need the prefix there.

setNextEvent(“admin:Product/edit”); looks for /module/admin/handlers/Product.cfc and calls the edit() action
overrideEvent(“admin:Product/edit”); looks for /module/admin/handlers/Product.cfc and calls the edit() action
runEvent(“admin:Viewlet/prepareNavigation”); = looks for /module/admin/handlers/Viewlet.cfc and calls prepareNavigation()

This works already!

I can also see maybe enhancing the setView(), setLayout() methods to not be context aware and pass in an argument for module. Would this work.

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