I'd like to create some routes based on data in a database table. I assume this will need to be done after the framework initializes so what I've done so far is created a new interceptor that runs on: afterConfigurationLoad
.
My interceptor receives a service from my model which will query the data I need to create the routes. However, I'm not sure how to add routes at this point. When I try and call addRoute()
directly I get an error Variable ADDROUTE is undefined.
so I guess addRoute()
doesn't exist in the framework Supertype.
Here's some sample code from my interceptor:
component {
property name="myService" inject="myService"; // injects my model which will get some data
/**
* afterConfigurationLoad
* Runs after the framework configucation loads
*/
void function afterConfigurationLoad( event, interceptData, buffer, rc, prc ){
// get some data which will be converted into routes
var myDataList = myService.list();
// loop through the data
for ( var data in myDataList ) {
// add our route. NOTE: I'll also want to populate the prc scope with a value
addRoute( pattern="/#data.slug#", handler="data", action="index" );
}
}
}
Edit 1: Using ColdBox v5.1.1
Update 1:
Brad's answer put me on the right track. I was unable to inject the router in my interceptor because it generated an error. However, I was able to get an instance of the router from within the function using getInstance( "router@coldbox" )
and then call route()
methods as needed to create my routes.
Important: Routes by default are appended to the routing table. You will likely need to prepend the routes if you want them to work.
Here's an updated version of the code which will work:
Solution 1:
component {
property name="myService" inject="myService"; // injects my model which will get some data
/**
* afterConfigurationLoad
* Runs after the framework configucation loads
*/
void function afterConfigurationLoad( event, interceptData, buffer, rc, prc ){
// instance the router
var router = getInstance( "router@coldbox" );
// get some data which will be converted into routes
var myDataList = myService.list();
// loop through the data
for ( var data in myDataList ) {
// prepend our route
router.route( "/#data.slug#" ).prcAppend( { id : #data.id# } ).to( "data.index" ).prepend();
}
}
}
Additionally, there may be a simpler way to solve this problem by simply injecting the model service into the `config/router.cfc' configuration file and adding any dynamic routes that way.
Solution 2:
component {
property name="myService" inject="myService"; // inject the model
function configure() {
setFullRewrites( true );
// get the data I need from the model for dynamic routes
var myDataList = myService.list();
// loop through the data
for ( var data in myDataList ) {
// add the dynamic route
router.route( "/#data.slug#" ).prcAppend( { id : #data.id# } ).to( "data.index" );
}
route( ":handler/:action?" ).end();
}
}
Solution 3:
As it turns out, when the framework initializes, the interceptors get loaded first so not all dependencies will be available yet. Brad suggested using the provider namespace in the property which should also be an acceptable solution.
component {
property name="myService" inject="myService"; // injects my model which will get some data
property name="router" inject="provider:router@coldbox";
/**
* afterConfigurationLoad
* Runs after the framework configucation loads
*/
void function afterConfigurationLoad( event, interceptData, buffer, rc, prc ){
// get some data which will be converted into routes
var myDataList = myService.list();
// loop through the data
for ( var data in myDataList ) {
// prepend our route
router.route( "/#data.slug#" ).prcAppend( { id : #data.id# } ).to( "data.index" ).prepend();
}
}
}
Inject the ColdBox Router
property name='router' inject='router@coldbox';
and call its methods detailed here in the API docs:
http://apidocs.ortussolutions.com/coldbox/5.2.0/index.html?coldbox/system/web/routing/Router.html
The addRoute()
method is part of that CFC.