Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Event handlers are ColdBox's version of controllers in the MVC design pattern. So every time you hear "event handler", you are talking about a controller that can listen to external events or internal events in ColdBox. Event handlers are responsible for controlling your application flow, calling business logic, preparing a display to a user and much more.
All your handlers will be stored in the handlers folder of your application template. If you get to the point where your application needs even more decoupling and separation, please consider building ColdBox Modules instead.
Tip: You can create packages or sub-folders inside of the handlers directory. This is encouraged on large applications so you can organize or package handlers logically to facilitate better maintenance and URL experience.
You can also declare a HandlersExternalLocation
directive in your Configuration CFC. This will be a dot notation path or instantiation path where more external event handlers can be found.
If an external event handler has the same name as an internal conventions event, the internal conventions event will take precedence.
By default, ColdBox will only scan for event handlers on startup. For development we highly encourage you leverage the following configuration directives:
Event handlers are CFCs that will respond to FORM posts, HTTP requests and/or remote requests (like Flex,Air, SOAP, REST) via an incoming RC variable called event or by URL mappings (Which we saw in the previous section).
You can also remove the inheritance from the CFC and WireBox will extend the coldbox.system.EventHandler
for you using Virtual Inheritance.
Event Handlers are treated as singletons by ColdBox, so make sure you make them thread-safe and properly scoped. Persistence is controlled by the coldbox.handlerCaching
directive
They are composed of functions which are called actions that will always have the following signature:
Each action receives three arguments:
event
- An object that models and is used to work with the current request
rc
- A struct that contains both URL/FORM
variables (unsafe data)
prc
- A secondary struct that is private. This structure is only accessible from within your application (safe data)
An action will usually do one of the following:
Set a view/layout to render
Return HTML
Return Complex Data which is converted to JSON by default
Relocate to another event/URL Route
The default action for all event handlers is called index()
. This means that when you execute an event, you can omit the index if you so desire.
So what about private
functions? Private functions are not executable from the outside world, but can be executed internally via a function available to all handlers called runEvent()
, which we will explore later.
It is important to note that there is a pre-defined object model behind every event handler controller that will enable you to do your work more efficiently. The following are the automatically generated properties every event handler makes available in their variables
scope:)
cachebox : A reference to the CacheBox library (coldbox.system.cache.CacheFactory
)
controller : A reference to the Application Controller (coldbox.system.web.Controller
)
flash: A flash memory object (coldbox.system.web.flash.AbstractFlashScope
)
logbox: A reference to the application LogBox (coldbox.system.logging.LogBox
)
log: A pre-configured logging logger object (coldbox.system.logging.Logger
)
wirebox : A reference to the application WireBox Injector (coldbox.system.ioc.Injector
)
$super: A reference to the virtual super class if using non-inheritance approach.
Events are determined via a special variable that can be sent in via the FORM, URL, or REMOTELY called event
. If no event is detected as an incoming variable, the framework will look in the configuration directives for the DefaultEvent
and use that instead. If you did not set a DefaultEvent
setting then the framework will use the following convention for you: main.index
Hint : You can even change the event
variable name by updating the EventName
setting in your coldbox
configuration directive.
Please note that ColdBox supports both normal variable routing and URL mapping routing, usually referred to as pretty URLs.
In order to call them you will use the following event syntax notation format:
no event : Default event by convention is main.index
event={handler} : Default action method by convention is index()
event={handler}.{action} : Explicit handler + action method
event={package}.{handler}.{action} : Packaged notation
event={module}:{package}.{handler}.{action} : Module Notation (See ColdBox Modules)
This looks very similar to a Java or CFC method call, example: String.getLength(),
but without the parentheses. Once the event variable is set and detected by the framework, the framework will tokenize the event string to retrieve the CFC and action call to validate it against the internal registry of registered events. It then continues to instantiate the event handler CFC or retrieve it from cache, finally executing the event handler's action method.
Examples
The framework provides you with the relocate()
method that you can use to relocate to other events thanks to the framework super type object, the grand daddy of all things ColdBox.
It is extremely important that you use this method when relocating instead of the native ColdFusion methods as it allows you to gracefully relocate to other events or external URIs. By graceful, we mean it does a lot more behind the scenes like making sure the flash scope is persisted, logging, post processing interceptions can occur and safe relocations.
So always remember that you relocate via relocate()
and if I asked you: "Where in the world does event handlers get this method from?", you need to answer: "From the super typed inheritance".
The event
object is the object that will let you set the views that you want to render, so please explore its API in the CFC Docs. To quickly set a view to render, do the following:
The view name is the name of the template in the views directory without appending the .cfm. If the view is inside another directory, you would do this:
The views you set will use the default layout defined in your configuration file which by default is the layouts/Main.cfm
We recommend that you set your views following the naming convention of your event. If your event is users.index, your view should be users/index. This will go a long way with maintainability and consistency and also will activate implicit views where you don't even have to use the set view method call.
You can also use the setView(), setLayout()
methods to tell the framework which view and layout combination to use:
You can also tell the framework to set a view for rendering by itself with no layout using the noLayout
argument
Here are the arguments for the setView()
method:
You can leverage the caching arguments in the setView()
method in order to render and cache the output of the views once the framework renders it. These cached views will be stored in the template cache region, which you can retrieve or purge by talking to it: getCache( 'template' )
.
Data can be passed from your handler to the view via rc or prc. If you want to pass data to a view without polluting rc and prc, you can pass it directly via the args parameter, much like a method call.
Access the data in the view like so:
If you don't want to, you don't have to. The framework gives you a method in the event object that you can use if this specific request should just terminate gracefully and not render anything at all. All you need to do is use the event object to call on the noRender()
method and it will present to the user a lovely white page of death.
We would recommend you use the private request collection (prc
) for setting manual data and using the standard request collection (rc
) for reading the user's unsafe request variables. This way a clear distinction can be made on what was sent from the user and what was set by your code.
Important The most important paradigm shift from procedural to an MVC framework is that you NO LONGER will be talking to URL, FORM, REQUEST or any ColdFusion scope from within your handlers, layouts, and views. The request collection already has URL, FORM, and REQUEST scope capabilities, so leverage it.
Please see the for further investigation of all the goodness of methods you have available.
We all need values in our applications. That is why we interact with the in order to place data from our model layer into it so our views can display it, or to retrieve data from a user's request. You will either interact with the event object to get/set values or put/read values directly via the received rc
and prc
references.