Brad Wood

January 24, 2017

Spread the word

Share your thoughts

ColdBox modules have revolutionized the way that CFML developers can reuse and organize code.  Modules follow an HMVC, or Hierarchical MVC pattern that allows you to not only break apart your CFML app into smaller chunks, but to stack those pieces into a hierarchy that really makes sense of your code.  We also call this module inceptions-- the act of nesting modules inside of each other.  

So, a question came across the ColdBox Google group today asking about how to access events from within nested modules and how that manifests itself in the URL.  Before I responded, I spun up a quick site in CommandBox to test and I found to my dismay that the answer was very difficult to find in our docs.  As such, I figured a quick blog post was in order since it's fairly easy to set up if you know what to do.

Module Routing

First, a quick review of how module routes work.  Let's create a quick site in CommandBox to test with (feel free to follow along locally).

CommandBox> mkdir moduleRouting --cd
CommandBox> coldbox create app
CommandBox> coldbox create module admin
CommandBox> server start --rewritesEnable

Ok, in a few seconds a browser should pop up with your fresh ColdBox site.  We've created a simple module called "admin".  There's two ways you can hit the admin module (Add in the port for your server):

  • http://localhost/index.cfm?event=admin:home.index
  • http://localhost/admin/home/index

The latter is what we're going to focus on.  It uses SES URLs and the URL rewriting inherent in CommandBox to produce a nice, clean URL.  In fact, you can shorten that last URL down to http://localhost/admin which uses the conventions and defaults inside the framework to default the home an index part.  That default route of "/admin" comes from the admin module's ModuleConfig.cfc where it says 

this.entryPoint = "admin";

This can really be anything, but it default to the name of the module.

Nested Modules

Ok, let's throw an "orders" module inside of our "admin" module.  We'll assume the administrator portion of your site has a subsection to handle orders.

CommandBox> cd modules_app/admin
CommandBox> coldbox create module name=orders directory=modules
CommandBox> cd ../../
CommandBox> coldbox reinit

Ok, so now we have this setup:

Your ColdBox:
 +- Admin module
    +- Orders module

So, how do we access the default event from our nested "orders" module in the url?  Well, by default the nested module's entry point is simply going to be "orders" which means the default URLs look like this:


But what if we want to clean that up and show the same nesting in the URL that matches our module hierarchy?  There's two ways to approach this.

Override the entry point for the nested module

Ok, so let's open up the ModuleConfig.cfc from our nested orders module in your default editor:

CommandBox> edit modules_app/admin/modules/orders/ModuleConfig.cfc

Find the entry point defined before the configure method and change it like so:

// Module Entry Point
this.entryPoint = "admin/orders";

Now, issue another ColdBox reinit, and the following URL should take you to your orders module homepage:


Add module routing in the parent

Ok, the above method works great if you have control over all the code.  What if the "orders" module was something installed by CommandBox as a 3rd party dependency and you don't want to or simply cannot edit the code. No worries, our "admin" module can declare a passthrough route that tells ColdBox that we want to point to the nested module under a certain routing namespace.  Let's open up the parent admin module's config:

CommandBox> edit modules_app/admin/ModuleConfig.cfc

Find the array of routing info and add a new line to it:

// SES Routes
routes = [
    // Module Entry Point
    { pattern="/", handler="home", action="index" },
    // Passthrough route for nested module
    { pattern="/orders, moduleRouting="orders" },
    // Convention Route
    { pattern="/:handler/:action?" }

Ok, so we added the moduleRouting bit.  The pattern is whatever URL placeholder you want to use and is automatically appended to the entry point of the admin module.  The moduleRouting key points to the real name of the nested module that we want to route the pattern to. This gives us the same result as the previous method, but we never have to touch the nested module's code.


And in case you're wondering-- the events inside the nested module just append to the URL like you would expect.  Basically, any convention routes, or custom routes in your inner module just append themselves onto the end of the pattern above.


Clean up, aisle 7

OK, our work here is done.  If you followed along at home, congrats.  Let's pretend this never happened and get back to work!

CommandBox> server stop --forget
CommandBox> cd ../ && rm moduleRouting --recurse --force




Add Your Comment

Recent Entries

Ortus March Newsletter

Ortus March Newsletter

Welcome to Ortus Solutions’ monthly roundup, where we're thrilled to showcase cutting-edge advancements, product updates, and exciting events! Join us as we delve into the latest innovations shaping the future of technology.

Maria Jose Herrera
Maria Jose Herrera
April 01, 2024
Into the Box 2024 Last Early Bird Days!

Into the Box 2024 Last Early Bird Days!

Time is ticking, with less than 60 days remaining until the excitement of Into the Box 2024 unfolds! Don't let this golden opportunity slip away; our exclusive Early Bird Pricing is here for a limited time only, available until March 31st. Why wait? Secure your seat now and take advantage of this steal!

Maria Jose Herrera
Maria Jose Herrera
March 20, 2024
Ortus February Newsletter 2024

Ortus February Newsletter 2024

Welcome to Ortus Solutions’ monthly roundup, where we're thrilled to showcase cutting-edge advancements, product updates, and exciting events! Join us as we delve into the latest innovations shaping the future of technology.

Maria Jose Herrera
Maria Jose Herrera
March 06, 2024