Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
A historical snapshot of all major versions of ColdBox
In this section you will find the release notes for each version we release under this major version. If you are looking for the release notes of previous major versions use the version switcher at the top left of this documentation book. Here is a breakdown of our major version releases.
Version 3.0 - March 2011
Version 2.0 - April 2007
Version 1.0 - June 2006
May 1, 2023
Github actions for LTS Releases
LTS Updates
COLDBOX-1219 CFProvider ACF versions are Hard-Coded
WIREBOX-132 WireBox caches Singletons even if their autowired dependencies throw exceptions.
May 13, 2024
COLDBOX-1274 javacasting to long for new Java LocalDateTime instead of int, Adobe not doing type promotion
COLDBOX-1279 Render encapsulator bleed of this scope by engines
COLDBOX-1273 Removal of deprecated CFML functions in core
COLDBOX-1275 Improved engine detection by the CFMLEngine feature class
COLDBOX-1278 Remove unsafe evaluate function usage
ColdBox is a conventions-based HMVC web development framework for ColdFusion (CFML).
ColdBox Hierarchical MVC is the de-facto enterprise-level HMVC framework for ColdFusion (CFML) developers. It's professionally backed, conventions-based, modular, highly extensible, and productive. Getting started with ColdBox is quick and painless. ColdBox takes the pain out of development by giving you a standardized methodology for modern ColdFusion (CFML) development with features such as:
Much More
It provides a set of reusable code and tools that can be used to increase your development productivity as well as a development standard for working in team environments.
ColdBox is maintained under the Semantic Versioning guidelines as much as possible.Releases will be numbered with the following format:
And constructed with the following guidelines:
Breaking backward compatibility bumps the major (and resets the minor and patch)
New additions without breaking backward compatibility bumps the minor (and resets the patch)
Bug fixes and misc changes bumps the patch
The ColdBox Platform is open source and licensed under the Apache 2 License.
Copyright by Ortus Solutions, Corp
ColdBox, CacheBox, WireBox, LogBox are registered trademarks by Ortus Solutions, Corp
The Ortus Community is the way to get any type of help for our entire platform and modules: https://community.ortussolutions.com
We all make mistakes from time to time :) So why not let us know about it and help us out. We also love pull requests, so please star us and fork us at: https://github.com/coldbox/coldbox-platform
ColdBox is a professional open source software backed by Ortus Solutions, Corp offering services like:
Custom Development
Professional Support & Mentoring
Training
Server Tuning
Security Hardening
Code Reviews
Official Site: https://www.coldbox.org
CFCasts Video Training: http://www.cfcasts.com
Source Code: https://github.com/coldbox/coldbox-platform
Bug Tracker: https://ortussolutions.atlassian.net/browse/COLDBOX
Twitter: @coldbox
Facebook: https://www.facebook.com/coldboxplatform
Vimeo Channel: https://vimeo.com/channels/coldbox
Because of His grace, this project exists. If you don't like this, then don't read it, it's not for you.
"Therefore being justified by faith, we have peace with God through our Lord Jesus Christ: By whom also we have access by faith into this grace wherein we stand, and rejoice in hope of the glory of God." Romans 5:5
ColdBox 6.4.0 is more of a major than a minor release due to the amount of work we have done to bring you one of the most revolutionary features of this framework: Scheduled Tasks.
Scheduled tasks have always been a point of soreness for many developers in ANY language. Especially choosing where to place them for execution: should it be cron? windows task scheduler? ColdFusion engine? Jenkins, Gitlab? and the list goes on and on.
The ColdBox Scheduled Tasks offers a fresh, programmatic and human approach to scheduling tasks on your server and multi-server application. It allows you to define your tasks in a portable Scheduler we lovingly call the Scheduler.cfc
which not only can be used to define your tasks, but also monitor all of their life-cycles and metrics of tasks. Since ColdBox is also hierarchical, it allows for every single ColdBox Module to also define a Scheduler
and register their own tasks as well. This is a revolutionary approach to scheduling tasks in an HMVC application.
You can learn all about them in our two sections:
Bugs
Improvements
New Features
Bugs
Remove debug writedumps left over from previous testing
Fix instance of bad route merging the routes but loosing the handler
Minor Improvements
Update Response Pagination Properties for Case-Sensitive Engines
default status code to 302 in the internal relocate() just like CFML does instead of 0 and eliminate source
Update the internal cfml engine checker to have more engine based feature checkers
Switch isInstance
check on renderdata in controller to secondary of $renderdata check to optimize speed
Bugs
Bug in JDBCMetadataIndexer sortedKeys() using non-existent variable arguments.objectKey
Minor Improvements
JDBCStore Dynamically generate queryExecute options + new config to always include DSN due to ACF issues
Router closure responses not marshalling complex content to json
New virtual app was always starting up the virtual coldbox app instead of checking if it was running already
Updated Missing Action Response Code to 404 instead of 405
All core async proxies should send exceptions to the error log
New config/ColdBox.cfc
global injections: webMapping
, coldboxVersion
Funnel all out and err logging on a ColdBox Scheduled Task to LogBox
Remove HandlerTestCase
as it is no longer in usage.
Fixes issues with Adobe losing App Context in Scheduled Tasks. You can now run scheduled tasks in Adobe with full app support.
When running scheduled tasks in ACF loading of contexts produce a null pointer exception
DataMarshaller
no longer accepts 'row', 'column' or 'struct' as a valid argument.
Convert util to script and optimize
Add more debugging when exceptions occur when loading/unloading thread contexts
Implement caching strategy for application helper lookups into the default
cache instead of the template
cache.
New SchedulerService
that mointors and registers application scheduled tasks in an HMVC fashion
Added out and error stream helpers to Scheduled Tasks for better debugging
newTask
() method on scheduled executor to replace nameless newSchedule
New scheduler object to keep track and metrics of registered tasks
New Scheduled Task with life-cycles and metrics
New async.time package to deal with periods, durations, time offsets and so much more
Added CFML Duration and Periods to async manager so task executions can be nicer and pin point accuracy
Allow structs for query strings when doing relocations
Encapsulate any type of exception in the REST Handler in a onAnyOtherException
() action which can also be overidden by concrete handlers
Add registration and activation timestamps to the a module configuration object for active profiling.
Rename renderLayout()
to just layout()
and deprecate it for v7
Rename renderView(
) to just view()
and deprecate it for v7
virtual inheritance causes double inits
on objects that do not have a constructor and their parent does.
onDIComplete
() is called twice using virtual inheritance
New coldbox dsl => coldbox:appScheduler
which gives you the appScheduler@coldbox
instance
new injection dsl: wirebox:asyncManager
July 9th, 2021
Please note that the following ticket corrects behavior in ColdBox that MIGHT affect interceptors
that have injected dependencies that have the same name as application helper methods from other modules.
Example:
The interceptor above has a dependency of auth
from the cbauth
module. However, the cbauth
module also has an application helper called auth
. So at runtime, this will throw an exception:
This is because now we can't inject the cbauth
mixin because we already have a cbauth
dependency injected. The resolution, is to RENAME the injection variables so they don't collide with module application helpers.
Regression
COLDBOX-1024 Module helpers no longer injected/mixed into interceptors
COLDBOX-1024 Module helpers no longer injected/mixed into interceptors
COLDBOX-1026 Update BeanPopulator
for Hibernate 5 detection in Lucee new extension
COLDBOX-1025 Added back the finally block, just to make sure cleanup are done in bootstrap reinits
COLDBOX-1021 fix lastBusinessDay
tests to reflect if the now is the actual last business day of the month
COLDBOX-1020 ColdBox does not allow for non-existent client cookies when using Flash RAM
COLDBOX-1019 ACF 2021 introduced getTimezone()
so we need to be specific when getting timezones in the scheduler or else it fails
COLDBOX-1016 CF-2018 stats.lastResult
is null when task->call have runEvent("xxxx")
COLDBOX-1015 Element cleaner not matching on query strings due to misordering of map keys. Use a TreepMap
to normalize ordering so event caching and view caching cleanups can ocur.
COLDBOX-1014 response object cached response was never used, rely on the master bootstrap ColdBox cache response header
COLDBOX-1013 RendererEncapsulator
overwrites view()
-Method from FrameworkSupertype
COLDBOX-1010 this.nullSupport = true
breaks coldbox
COLDBOX-1008 ScheduleTask
listeners are only testing for isClosure()
and lambdas return false, so do an or check for isCustomFunction() to
support lambdas
COLDBOX-1007 scheduled task doesn't listen to when()
in Scheduler.cfc
COLDBOX-1004 Custom matchers debug()
function not found since it's injected in isolation
COLDBOX-1003 Scheduler service DI constructor argument was using the string literal instead of the string value for the scheduler name
COLDBOX-1002 added this scope to getTimezone()
to address issue with ACF-2021 bif
COLDBOX-1001 category not logged correctly in async loggers
COLDBOX-1023 Readjustments to fail fast and reloading procedures when there are exceptions and reiniting becomes impossible.
COLDBOX-1018 Enable proxy to use the ColdBox app key defined in the bootstrap instead of hard coding it
COLDBOX-1017 Delay loadApplicationHelpers()
in interceptors so modules can contribute udf helpers and even core interceptors can load them.
COLDBOX-1012 Move coldbox inited flag to after after aspects load, so we can make sure all modules are loaded before serving requests
COLDBOX-1009 RESTHandler capture JWT TokenException to authentication failures
CACHEBOX-68 BlackHoleStore never finishes reap() method
ColdBox 6.3.0 is a minor release that squashes lots of bugs and does tons of improvements for performance!
Lucee 4.5 support has been dropped.
ColdFusion 11 support has been dropped. Adobe doesn't support them anymore, so neither do we.
The following settings have been changed and altering behavior:
coldbox.autoMapModels
is now defaulted to true
Which means that all your models will be MAPPED for you. If you have specific mappers in your config/WireBox.cfc make sure they override the mapping or turn this setting false.
coldbox.onInvalidEvent
has been REMOVED in preference to coldbox.invalidEventHandler
coldbox.jsonPayloadToRC
is now defaulted to true
The buildLink()
method had an argument linkTo
. It has now changed to to
to provide simplification
The SES
interceptor has finally been removed. You can now remove it from your interceptor declarations. If you are relying on the SES interceptor for routing, then you will need to access the RoutingService
via the following injection methods or retrieval methods:
This method was marked for deprecation in ColdBox 5 and now it is removed. You can use the getInstance()
method instead.
get()
method to $get()
All WireBox providers now implement the new interface which has changed the method of get()
to $get()
to avoid proxying to methods that already implement a get()
method. So if you are using the get()
method just update it to the new $get()
method.
The getSetting()
method does NOT include a fwSetting
boolean argument anymore. You can now use the getColdBoxSetting()
method instead.
This method has now been deprecated in favor of its shorthand announce().
This method will still work but it will be removed in the next major version. So just rename it now. Also note that the interceptData
has now changed to just data
This method was used in the event manager and interceptor service and has been marked for deprecation. Please use the method announce()
instead. Which is also a consistency in naming now.
setNextEvent()
RemovedThe method setNextEvent()
has been removed in favor of relocate().
We had deprecated this method in ColdBox 5.
These methods have been deprecated since version 4 and they are now removed.
getBufferObject()
getBufferString()
appendToBuffer()
clearBuffer()
Every interception listener receives the buffer
as an argument so there is no need to go to global functions for working with the buffer.
All interceptors receive arguments when listening, we have renamed the interceptData
to just data
. The old approach still works but it is marked as deprecated. So just rename it to data
Default Bug Report Files are now located in /coldbox/system/exceptions/
. Previously /coldbox/system/includes/
So make sure you update your CustomErrorTemplate
path to this new path:
The entire rendering mechanisms in ColdBox 6 have changed. We have retained backwards compatibility but there might be some loopholes that worked before that won't work now. Basically, the renderer is a singleton and each view renders in isolation. Meaning if a view sets a variable in it's variables
scope NO OTHER view will have access to it.
ColdBox 6.2.0 is a minor release with some major improvements in many areas like:
Async programming
Logging
Object creations
WireBox Mappings and Binders
This is a major change in the core as we have finally rewritten the WireBox Binder
and object Mapping
objects to script. This resulted in a 45-50% code reduction for those objects and an impressive 30% speed improvements when creating and processing mappings with the new binder processing optimizations. We analyzed every single line of code on these two objects and we are incredibly satisfied with the initial results.
That's right, we have some async goodness prepared for future versions when dealing with multiple directory mappings and much more.
It is also available to ANY ColdFusion application that is NOT running ColdBox. This is achieved by using either of our standalone libraries: WireBox, CacheBox and LogBox.
This version introduces the capability for you to tag your integration tests with an autowire
annotation on the component tag. By adding this annotation, your test object will be inspected and wired with dependencies just like any other WireBox object.
We have also included a new object coldbox.system.testing.CustomMatchers
which will register matchers into TestBox when doing integration tests. It will give you the nice ability to expect status codes and validation exceptions on RESTFul Requests via the ColdBox Response object.
toHaveStatus()
toHaveInvalidData()
We have had tons of updates and requests from our new exception handling experience in ColdBox: Whoops! In this release we tackle CFML core engine files so they can render appropriately, AJAX rendering for exceptions and best of all a huge performance and size boost when dealing with exceptions. Even when dealing with exceptions we want the best and the fastest experience possible for our developers.
The previous approach whoops took was to read and load all the source code of all the templates that caused the exception. You could then navigate them to discover your faults. However, each template could be loaded from 1 to up to 10 times if the stack trace followed it. In this new update we provide source template caching and dynamic runtime injection and highlighting of the source code. This has granted us the following improvements in small test cases (Your improvements could be higher)
Author biographies of the ColdBox Platform
Luis has a passion for Jesus, tennis, golf, volleyball and anything electronic. Random Author Facts:
He played volleyball in the Salvadorean National Team at the tender age of 17
The Lord of the Rings and The Hobbit is something he reads every 5 years. (Geek!)
His first ever computer was a Texas Instrument TI-86 that his parents gave him in 1986. After some time digesting his very first BASIC book, he had written his own tic-tac-toe game at the age of 9. (Extra geek!)
He has a geek love for circuits, micro-controllers and overall embedded systems.
He has of late (during old age) become a fan of organic gardening.
Keep Jesus number one in your life and in your heart. I did and it changed my life from desolation, defeat and failure to an abundant life full of love, thankfulness, joy and overwhelming peace. As this world breathes failure and fear upon any life, Jesus brings power, love and a sound mind to everybody!
“Trust in the LORD with all your heart, and do not lean on your own understanding.” – Proverbs 3:5
Jorge started working as project manager and business developer at Ortus Solutions, Corp. in 2013, . At Ortus he fell in love with software development and now enjoys taking part on software development projects and software documentation! He is a fellow Christian who loves to play the guitar, worship and rejoice in the Lord!
Therefore, if anyone is in Christ, the new creation has come: The old has gone, the new is here! 2 Corinthians 5:17
Brad's CommandBox Snake high score is 141.
[] - Renderer methods assume the module exists and throws exception when sending invalid url data
[] - Can no longer have duplicate routes with different conditions
[] - Colon (:) in URL Path Causes Exception Error
[] - invalidEventHandler does not work when calling invalid action on valid handler
[] - autowire annotation for test cases is not working as it should
[] - Fix declaring multiple resources at once
[] - AsyncManager threads don't release DB connections to pool for Adobe CF
[] - Add new exception type catch for the RestHandler: `PermissionDenied` to trap in valid authorizations
[] - Content type http header bypasses requestContext with render data - set explicit http header via request context
[] - Implement caching strategy for application helper lookups into the `template` cache
[] - Coldbox DataMarshaller Throws Error with Lucee-Light Engine
[] - Have the html helper manifests in local memory instead of the template cache to avoid cleanup issues
[] - Remove unecessary locks for view path setups in the renderer
[] - Remove unecessary lock in the bootstrap to get the controller reference, it's already there for the reload checks
[] - Module service now profiles registration and activation into the logs with the version and path of a module
The major compatibility issues will be covered as well as how to smoothly upgrade to this release from previous ColdBox versions. You can also check out the guide to give you a full overview of the changes.
We have done more runtime analysis on our asynchronous
package and we have optimized the heck out of it using the amazing Profilers! Especially the applyAll()
and collection based parallel computing. We reached a point where all of our tests cases where running faster than even native Lucee/Adobe 2021 parallel constructs. Below you can see a snapshot of our test bed creating 1000 transient objects with dependency injections and object populations using async constructs.
You can find our test bed here:
Just a reminder that the ColdBox async capabilities are all powered by the Java concurrency packages leveraging , and . It is not only true to the Java API but we have made tons of enhancements especially for ColdFusion and its dynamic nature. !
Thanks to Dom Watson () from PresideCMS () for many contributions to help clean up ColdBox view rendering! This release focuses on more performance and memory utilization updates, as well as refactoring external dependencies from pre singleton rendering approaches, which has resulted in more performance gains and lower memory usages on high rendering apps.
Original Size: 218.54 KB New Size: 145.22 KB About 30-40% reduction on size depending on repetition of the templates
Original Rendering Speed: 288ms New Rendering Speed: 76ms About 74-80% rendering improvements
[] - ExceptionBean
throws exception on weird ORM illegal access collection on scope dump
[] - Migration to cgi.server_name
and server_port
did not account for the incoming browser port but the cf service port
[] - getFullURL()
is not accounting for app mappings
[] - Invalid event handler detection was overriding some event handler beans
[] - timeUnits
had type mismatches when used in async futures' allApply
[] - Whoops should validate a file exists before trying to present it to the code viewer
[] - Add timeout
and timeUnit
arguments to the allApply()
method directly when using Futures
[] - New global settings: sesBasePath
and HtmlBasePath
that represent the pathing with no host and protocol
[] - new request context method getFullPath()
which returns the full url with no protocol or host
[] - New autowire
annotation or `variables.autowire
` on integration tests so ColdBox will autowire the test with dependencies via WireBox
[] - Store the test case metadata on ```variables.metadata``` so it can be reused by any helper within test operations
[] - New ColdBox CustomMatchers
object found at coldbox.system.testing.CustomMatchers
which is loaded on all tests
[] - migrating usage of cgi.http_host
to cgi.server_name
due to inconsistencies with proxy requests that affects caching and many other features
[] - ProcessStackTrace()
Creates Many Nested Spans, improved output HTML
[] - Improved safety reset for base test cases
[] - Performance optimizations for entire async package
[] - Refactored cgi server and port detections to improve testability and single responsibiilty principles
[] - Event caching now bases off the multi host key from the event.getSESBaseURL()
to improve consistencies and single responsibility
[] - encapsulate processEception()
from the bootstrap to within the exception objects
[] - better exception tracking for interceptor getProperty()
calls that don't exist
[] - RendererEncapsulator
: use of filter method for rendererVariables
is inefficient, migrated to less fluent but more performant approach.
[] - Update DateFormat
Mask to use lowercase "d" to be compatible with ACF2021
[] - Refactor viewsHelperRef
and layoutsHelperRef
to local renderer variables instead of settings, which resulted in even better speed improvements
[] - If in an Ajax request and an exception occurs using Whoops the view is unusable
[] - Whoops loads multiple files into the DOM for the templates in the stacktrace causing major slowdownsa
[] - Event caching now bases off the multi host key from the event.getSESBaseURL() to improve consistencies and single responsibility
[] - Update DateFormat
Mask to use lowercase "d" to be compatible with ACF2021
[] - Missing line break on file appender control string
[] - new shutdown()
method to process graceful shutdown of LogBox
[] - New logbox config onShutdown()
callback, which is called when LogBox has been shutdown
[] - New shutdown()
method can be now used in appenders that will be called when LogBox is shutdown
[] - parameter [binder] to function [process] is required but was not passed in When setting coldbox.autoMap to false and choosing either method of mapping a directory:
[] - ACF incompats with future combinations due to dumb elvis operator bug
[] - Pass the current injector
to the binder's life-cycle methods: onShutdown(), onLoad()
[] - Create a processEagerInits()
so it can process them at wirebox load
[] - Complete rewrite of the Mapping
object to script and performance optimizations
[] - Complete rewrite of the WireBox Binder
to script and optimizations
[] - New WireBox config: autoProcessMappings
which can be used to auto process metadata inspections on startup.
[] - jsonPayloadToRC
is not working in 6.2 update
[] - Random bug dealing with integration testing when dealing with routes vs direct events
[] - Regression: Remove default dsl of "" from initArg()
and addDIConstructorArgument()
[] - Regression: parentInjector() stopRecursions()
collision with internal property name
[] - Use Java URI for more resiliant getFullURL
to avoid double slashes
[] - wirebox metadata caching broken
[] - Standalone event pool interceptData
-> data not backwards compat
[] - WireBox not handling cachebox, logbox, and asyncmanager instances properly
[] - CacheBox not handling wirebox, logbox, and asynmanager instances properly
[] - Ignore interrupted exceptions from appenders' scheduler pool
Luis Majano is a Computer Engineer with over 15 years of software development and systems architecture experience. He was born in in the late 70’s, during a period of economical instability and civil war. He lived in El Salvador until 1995 and then moved to Miami, Florida where he completed his Bachelors of Science in Computer Engineering at
He is the CEO of , a consulting firm specializing in web development, ColdFusion (CFML), Java development and all open source professional services under the ColdBox, CommandBox and ContentBox stack. He is the creator of ColdBox, ContentBox, WireBox, MockBox, LogBox and anything “BOX”, and contributes to many open source projects. You can read his blog at
Jorge is an Industrial and Systems Engineer born in El Salvador. After finishing his Bachelor studies at the Monterrey Institute of Technology and Higher Education , Mexico, he went back to his home country where he worked as the COO of. In 2012 he left El Salvador and moved to Switzerland in pursuit of the love of his life. He married her and today he resides in Basel with his lovely wife Marta and their daughter Sofía.
Brad grew up in southern Missouri where he systematically disassembled every toy he ever owned which occasionally led to unintentional shock therapy (TVs hold charge long after they've been unplugged, you know) After high school he majored in Computer Science with a music minor at (Olathe, KS). Today he lives in Kansas City with his wife and three girls where he still disassembles most of his belongings (including automobiles) just with a slightly higher success rate of putting them back together again.) Brad enjoys church, all sorts of international food, and the great outdoors.
Brad has been programming CFML for 12+ years and has used every version of CF since 4.5. He first fell in love with ColdFusion as a way to easily connect a database to his website for dynamic pages. Brad blogs at () and likes to work on solder-at-home digital and analog circuits with his daughter as well as building projects with Arduino-based microcontrollers.
[] - getStoreMetadataReport()
- wrong order of the reduce()
parameters
[] - Refactor the way cffeed
is used so that ACF 2021 doesn't choke on first startups, only when used
ColdBox provides you with a nice method for generating links between events by leveraging an object called event
that is accessible in all of your layouts/views and event handlers. This event
object is called behind the scenes the request context object, which models the incoming request and even contains all of your incoming FORM
and URL
variables in a structure called rc
.
Tip: You will use the event object to set views, set layouts, set HTTP headers, read HTTP headers, convert data to other types (json,xml,pdf), and much more.
The method in the request context that builds links is called: buildLink()
. Here are some of the arguments you can use:
Edit the views/virtual/hello.cfm
page and wrap the content in a cfoutput
and create a link to the main ColdBox event, which by convention is main.index
. You can use main.index
or just main
(Remember that index
is the default action)
This code will generate a link to the main.index
event in a search engine safe manner and in SSL detection mode. Go execute the event: http://localhost:{port}/virtual/hello
and click on the generated URL, you will now be navigating to the default event /main/index
. This technique will also apply to FORM submissions:
Tip You can visit our API Docs for further information about the event
object and the buildLink
method: http://apidocs.ortussolutions.com/coldbox/current/index.html?coldbox/system/web/context/RequestContext.html.
For extra credit try to use more of the buildLink
arguments.
ColdBox allows you to manipulate the incoming URL so you can create robust URL strategies especially for RESTFul services. This is all done by convention and you can configure it via the application router: config/Router.cfc
for more granular control.
Out of the box we provide you with convention based routing that maps the URL to modules/folders/handlers and actions.
route( "/:handler/:action" ).end()
We have now seen how to execute events via nice URLs. Behind the scenes, ColdBox translates the URL into an executable event string just like if you were using a normal URL string:
/main/index
-> ?event=main.index
/virtual/hello
-> ?event=virtual.hello
/admin/users/list
-> ?event=admin.users.list
/handler/action/name/value
-> ?event=handler.action&name=value
/handler/action/name
-> ?event=handler.action&name=
By convention, any name-value pairs detected after an event variable will be treated as an incoming URL
variables. If there is no pair, then the value will be an empty string.
Tip: By default the ColdBox application templates are using full URL rewrites. If your web server does not support them, then open the config/Router.cfc
and change the full rewrites method to false: setFullRewrites( false ).
Every time the framework renders a view, it will try to leverage the default layout which is located in layouts/Main.cfm
by convention. This is an HTML file that gives format to your output and contains the location of where the view you want should be rendered.
Tip : The request context can also be used to choose a different layout at runtime via the event.setLayout()
method or the layout
argument in the event.setView()
method.
Tip : The request context can also be used to render a view with NO layout at all via the event.noLayout()
method.
This location is identified by the following code: renderView()
The call to the renderView()
method with no arguments tells the framework to render the view that was set using event.setView()
. This is called a rendering region. You can use as many rendering regions within layouts or even within views themselves.
Named Regions: The setView()
method even allows you to name these regions and then render them in any layout or other views using the name
argument.
Let's create a new simple layout with two rendering regions. Open up CommandBox and issue the following commands:
Open the layouts/Funky.cfm
layout and let's modify it a bit by adding the footer view as a rendering region.
If you are use to using cfinclude
to reuse templates, think about it the same way. renderview()
is a much more powerful cfinclude.
Now, let's open the handler we created before called handlers/hello.cfc
and add some code to use our new layout explicitly via adding a layout
argument to our setView()
call.
Go execute the event now: http://localhost:{port}/hello/index
and you will see the view rendered with the words funky layout
and footer view
at the bottom. Eureka, you have now created a layout.
You can also leverage the function event.setLayout( "Funky" )
to change layouts and even concatenate the calls:
event
.setView( "hello/index" )
.setLayout( "Funky" );
Out of the box, ColdBox gives you all the RESTFul capabilities you will need to create robust and scalable RESTFul services. Let's add some RESTFul capabilities to our contact listing we created in the previous section.
Tip: You can find much more information about building ColdBox RESTFul services in our full docs.
If you know beforehand what type of format you will be responding with, you can leverage ColdBox auto-marshalling in your handlers. By default, ColdBox detects any return value from handlers and if they are complex it will convert them to JSON automatically for you:
ColdBox detects the array and automatically serializes it to JSON. Easy Peasy!
The request context object has a special function called renderData()
that can take any type of data and marshall (convert) it for you to other formats like xml, json, wddx, pdf, text, html
or your own type.
Tip: You can find more information at the API Docs for renderData()
here http://apidocs.ortussolutions.com/coldbox/current/index.html?coldbox/system/web/context/RequestContext.html#renderData()
So let's open the handlers/contacts.cfc
and add to our current code:
We have added the following line:
This tells ColdBox to render the contacts data in 4 formats: xml, json, pdf and html. WOW! So how would you trigger each format? Via the URL of course.
ColdBox has the ability to detect formats via URL extensions or an incoming Accepts
header. If no extension is sent, then ColdBox attempts to determine the format by inspecting the Accepts
header. If we still can't figure out what format to choose, the default of html
is selected for you.
Tip: You can also avoid the extension and pass a URL argument called format
with the correct format type: ?format=json
.
Let's add a new route to our system that is more RESTFul than /contacts/index.json
. You will do so by leveraging the application's router found at config/Router.cfc
. Find the configure()
method and let's add a new route:
The route()
method allows you to register new URL patterns in your application and immediately route them to a target event. You can even give it a human readable name that can be later referenced in the buildLink()
method.
Make sure you add routes above the default ColdBox route. If not, your route will never fire.
We have now created a new URL route called /api/contacts
that if detected will execute the contacts.index
event. Now reinit the application, why, well we changed the application router and we need the changes to take effect.
Tip: Every time you add new routes make sure you reinit the application: http://localhost:{port}/?fwreinit
.
You can now visit the new URL pattern and you have successfully built a RESTFul API for your contacts.
You can find much more about routing in our full docs
A 60 minute guide to start working with ColdBox
This guide has been designed to get you started with ColdBox in fewer than 60 minutes. We will take you by the hand and help you build a RESTFul application in 60 minutes or fewer. After you complete this guide, we encourage you to move on to the Getting Started Guide and then to the other guides in this book.
You can find the source code of this quickstart here: https://github.com/coldbox-samples/60-minute-quickstart
Please make sure you download and install the latest CommandBox CLI. We will show you how in the Installing ColdBox section.
Grab a cup of coffee or tea
Get comfortable
The Ortus Community is the way to get any type of help for our entire platform and modules: https://community.ortussolutions.com
Welcome to the world of ColdBox!
We are excited you are taking this development journey with us. Before we get started with ColdBox let's install CommandBox CLI, which will allow you to install/uninstall dependencies, start servers, have a REPL tool and much more.
ColdBox has the following supported IDE Tools:
The first step in our journey is to install CommandBox. CommandBox is a ColdFusion (CFML) Command Line Interface (CLI), REPL, Package Manager and Embedded Server. We will be using CommandBox for almost every exercise in this book and it will also allow you to get up and running with ColdFusion and ColdBox in a much speedier manner.
However, you can use your own ColdFusion server setup as you see fit. We use CommandBox as everything is scriptable, portable and fast!
You can download CommandBox from the official site: https://www.ortussolutions.com/products/commandbox#download and install in your preferred Operating System (Windows, Mac, *unix). CommandBox comes in two flavors:
No Java Runtime (30mb)
Embedded Runtime (80mb)
So make sure you choose your desired installation path and follow the instructions here: https://commandbox.ortusbooks.com/setup/installation
Once you download and expand CommandBox you will have the box.exe
or box
binary, which you can place in your Windows Path or *Unix /usr/bin
folder to have it available system wide. Then just open the binary and CommandBox will unpack itself your user's directory: {User}/.CommandBox
. This happens only once and the next thing you know, you are in the CommandBox interactive shell!
We will be able to execute a-la-carte commands from our command line or go into the interactive shell for multiple commands. We recommend the interactive shell as it is faster and can remain open in your project root.
All examples in this book are based on the fact of having an interactive shell open.
To get started open the CommandBox binary or enter the shell by typing box
in your terminal or console. Then let's create a new folder and install ColdBox into a directory.
CommandBox will resolve coldbox
from ForgeBox (www.forgebox.io), use the latest version available, download and install it in this folder alongside a box.json
file which represents your application package.
Tip : You can also install the latest bleeding edge version by using the coldbox@be
slug instead, or any previous version.
CommandBox can now track this version of ColdBox for you in this directory. In the next section we will scaffold a ColdBox application using an application template.
You can find many scaffolding templates for ColdBox in our Github organization: github.com/coldbox-templates
To uninstall ColdBox from this application folder just type uninstall coldbox
. Try it out!
To update ColdBox from a previous version, just type update coldbox
.
Let's complete our saga into MVC by developing the M, which stands for model. This layer is all your business logic, queries, external dependencies, etc. of your application, which represents the problem to solve or the domain to solve.
This layer is controlled by WireBox, the dependency injection framework within ColdBox, which will give you the flexibility of wiring your objects and persisting them for you.
Let's create a simple contact listing, so open up CommandBox and issue the following command:
This will create a models/ContactService.cfc
with a getAll()
method and a companion unit test at tests/specs/unit/ContactServiceTest.cfc
. Let's open the model object:
Notice the singleton
annotation on the component tag. This tells WireBox that this service should be cached for the entire application life-span. If you remove the annotation, then the service will become a transient object, which means that it will be re-created every time it is requested.
Let's mock an array of contacts so we can display them later. We can move this to a SQL call later.
We also have created a project to mock any type of data: MockDataCFC. Just use CommandBox to install it: install mockdatacfc
You can then leverage it to mock your contacts or any simple/complex data requirement.
We have now created our model so let's tell our event handler about it. Let's create a new handler using CommandBox:
This will create the handler/contacts.cfc
handler with an index()
action, the views/contacts/index.cfm
view and the accompanying integration test tests/specs/integration/contactsTest.cfc
.
Let's open the handler and add a new ColdFusion property
that will have a reference to our model object.
Please note that inject
annotation on the property
definition. This tells WireBox what model to inject into the handler's variables
scope.
By convention it looks in the models
folder for the value, which in our case is ContactService
. Now let's call it and place some data in the private request collection prc
so our views can use it.
Now that we have put the array of contacts into the prc
struct as aContacts
, let's display it to the screen using ColdBox's HTML Helper.
The ColdBox HTML Helper is a companion class that exists in all layouts and views that allows you to generate semantic HTML5 without the needed verbosity of nesting, or binding to ORM/Business objects.
Please check out the API Docs to discover the HTML Helper: http://apidocs.ortussolutions.com/coldbox/current/index.html?coldbox/system/modules/HTMLHelper/models/HTMLHelper.html
Open the contacts/index.cfm
and add the following to the view:
Note: If your models are singletons
, they will persist for the life-span of your ColdFusion application. To see code changes for singletons, you have to reinit the framework by using the ?fwreinit={password}
Url action or via CommandBox using coldbox reinit
. Please check out the API Docs to discover CommandBox: [https://apidocs.ortussolutions.com/commandbox/5.2.0/index.html]
That's it! Execute the event: http://localhost:{port}/contacts/index
and view the nice table of contacts being presented to you.
Congratulations, you have made a complete MVC circle!
Tip You can find much more information about models and dependency injection in our full docs
Event handlers are the controller layer in ColdBox and is what you will be executing via the URL
or a FORM
post. All event handlers are singletons, which means they are cached for the duration of the application, so always remember to var scope your variables in your functions.
Tip: For development we highly encourage you to turn handler caching off or you will have to reinit the application in every request, which is annoying. Open the config/ColdBox.cfc
and look for the coldbox.handlerCaching
setting.
By default this is already done for you on the application templates.
Go open the handlers/main.cfc
and let's explore the code.
Let's recap: Every action in ColdBox receives three arguments:
event
- An object that models and is used to work with the current request, called the request context.
rc
- A struct that contains both URL/FORM variables (unsafe data)
prc
- A secondary struct that is private only settable from within your application (safe data)
This line event.setView( "main/index" )
in the index
action told ColdBox to render a view back to the user found in views/main/index.cfm
.
ColdBox also has the concepts of layouts, which are essentially reusable views that can wrap other views or layouts. They allow you to reuse content so you can render views/layouts inside in a specific location in the CFML content. By convention, ColdBox looks for a layout called layouts/Main.cfm.
This is yet another convention, the default layout. Your application can have many layouts or non layouts at all.
We have now seen how to add handlers via CommandBox using the coldbox create handler
command and also execute them by convention by leveraging the following URL pattern:
Also remember, that if no action
is defined in the incoming URL then the default action of index
will be used.
Remember that the URL mappings support in ColdBox is what allows you to execute events in such a way from the URL. These are controlled by your application router: config/Router.cfc
Now, let's open the handler we created before called handlers/hello.cfc
and add some public and private variables to it so our views can render the variables.
Let's open the view now: views/hello/index.cfm
and change it to this:
Please note that we used the ColdFusion function encodeForHTML()
(https://cfdocs.org/encodeforhtml) on the public variable. Why? Because you can never trust the client and what they send, make sure you use the built-in ColdFusion encoding functions in order to avoid XSS hacks or worse on incoming public (rc
) variables.
If you execute the event now: http://localhost:{port}/hello/index
you will see a message of Hello nobody
.
Now change the incoming URL to this: http://localhost:{port}/hello/index?name=ColdBox
and you will see a message of Hello ColdBox
.
Tip: Please see the layouts and views section for in-depth information about them.
The ColdBox HMVC Platform is the de-facto enterprise-level HMVC framework for CFML developers.
The ColdBox HMVC Platform is the de-facto enterprise-level HMVC framework for CFML developers. It's professionally backed, highly extensible, and productive. Getting started with ColdBox is quick and painless. The only thing you need to begin is CommandBox, a command line tool for CFML developers.
This is a one-page introductory guide to ColdBox. If you are new to MVC or ColdBox, you can also leverage our 60 minute quick start guide as well.
The Ortus Community is the way to get any type of help for our entire platform and modules: https://community.ortussolutions.com
ColdBox has the following supported IDE Tools:
You can read through our one-page CommandBox Getting Started Guide. Or simply grab the CommandBox executable from the download page and double click it to run.
http://www.ortussolutions.com/products/commandbox
You should now be seeing a prompt that looks like this:
Now we're cooking with gas! Let's create a new ColdBox application. CommandBox comes with built-in commands for scaffolding out new sites as well as installing ColdBox and other libraries. We'll start by changing into an empty directory were we want our new app to live. If necessary, you can create a new folder.
Now let's ask CommandBox to create a new ColdBox app for us.
Tip: You can find many scaffolding templates for ColdBox in our Github organization: github.com/coldbox-templates
You can also issue a coldbox create app help
command and get help for the creation command.
This command will place several new folders and files in your working directory. Let's run the ls
command to view them.
Here's a rundown of the important bits (Even thought they might be more generated files/folders)
coldbox - This is the ColdBox framework managed by CommandBox
config/Coldbox.cfc - Your application configuration object
config/Router.cfc - Your application URL Router
handlers - Your controller layer, which in ColdBox they are called event handlers
layouts - Your HTML layouts
models - This holds your model CFCs
modules - This holds the CommandBox tracked modules
modules_app - This holds your app's modules
tests - Your test harness for unit and integration testing
views - Your HTML views will go here
Now that our shiny new MVC app is ready to go, let's fire it up using the embedded server built into CommandBox. You don't need any other software installed on your PC for this to work. CommandBox has it all!
In a few seconds, a browser window will appear with your running application. This is a full server with access to the web administrator where you can add data sources, mappings, or adjust the server settings. Notice the handy icon added to your system tray as well. The --rewritesEnable
flag will turn on some basic URL rewriting so we have nice, pretty URLs.
Tip: If you are creating an app to run on any other server than the commandbox server, you will need to manually set up URL rewriting. More info here: /the-basics/routing/requirements
ColdBox uses easy conventions to define the controllers and views in your app. Let's open up our main app controller in your default editor to have a looksie.
At the top, you'll see a function named "index". This represents the default action that runs for this controller, which in ColdBox land they are referred to as event handlers.
Now let's take a look in the main/index
view. It's located int he views
folder.
This line of code near the top of the view is what outputs the prc.welcomeMessage
variable we set in the controller.
Try changing the value being set in the handler and refresh your browser to see the change.
Let's define a new event handler now. Your controllers act as event handlers to respond to requests, REST API, or remote proxies.
Pull up CommandBox again and run this command.
That's it! You don't need to add any special configuration to declare your handler. Now we have a new handler called helloWorld
with actions index
, add
, edit
, and list
. The command also created a test case for our handler as well as stubbed-out views for each of the actions.
Now, let's re-initialize the framework to pick up our new handler by typing ?fwreinit=1
at the end of the URL.
Let's hit this new controller we created with a URL like so. Your port number will probably be different.
127.0.0.1:43272/helloWorld
Normally the URL would have index.cfm
before the /helloWorld
bit, but our --rewritesEnable
flag when we started the server makes this nicer URL possible.
ColdBox's MVC is simple, but its true power comes from the wide selection of modules you can install into your app to get additional functionality. You can checkout the full list of modules available on the FORGEBOX directory: www.forgebox.io.
Here's some useful examples:
BCrypt -- Industry-standard password hashing
cbdebugger -- For debugging Coldbox apps
cbjavaloader - For interacting with Java classes and libraries
cbMarkdown - For writing in markdown
cbMessagebox -- Display nice error/success messages
cborm -- Awesome ORM Services
cb18n -- For multilingual sites
cbt - ColdBox templating language
cbValidation - Back-end validation framework
qb - Fluent query builder and schema builder
route-visualizer - For visualizing your application routes
Install cbmessagebox
from the CommandBox prompt like this:
We can see the full list of packages by using the list
command.
Right now we can see that our app depends on coldbox
and cbmessagebox
to run. We'll use our new cbmessagebox
module in a few minutes. But first, we'll create a simple Model CFC to round out our MVC
app.
Models encapsulate the business logic your application. They can be services, beans, or DAOs. We'll use CommandBox to create a GreeterService
in our new app with a sayHello
method.
Tip: The --open
is a nice shortcut that opens our new model in our default editor after creating it.
Let's finish implementing the sayHello()
method by adding this return statement and save the file.
We can also add the word singleton
to the component declaration. This will tell WireBox to only create one instance of our service.
What is WireBox?
WireBox is a dependency injection framework that is included with ColdBox. It will manage all object creations, persistence and assembling. You don't have to worry about using new
or createobject()
for CFCs anymore.
Ok, let's open up that helloWorld
handler we created a while back. Remember, you can hit tab while typing to auto-complete your file names.
We'll inject our greeterService
and the cbmessagebox
service into the handler by adding these properties to the top of /handlers/helloWorld.cfc
.
What is this magical injection? Injection is a way to get references of other objects placed in the variables
scope of other objects. This makes your life easier as you don't have to be creating objects manually or even knowing where they exist.
This will put the instance of our services in the variables
scope where we can access it in our action methods.
And now in our index
method, we'll set the output of our service into an info
message.
One final piece. Open up the default layout located in layouts/Main.cfm
and find the #renderView()#
. Add this line right before it to render out the message box that we set in our handler.
Now hit your helloWorld
handler one final time with ?fwreinit=1
in the URL to see it all in action! (Again, your port number will most likely be different.
127.0.0.1:43272/helloWorld?fwreinit=1
Congratulations! In a matter of minutes, you have created a full MVC application. You installed a community module from ForgeBox, created a new handler/view and tied in business logic from a service model.
As easy as that was, you're just scratching the surface of what ColdBox can do for you. Continue reading this book to learn more about:
Environment-specific configuration
Easy SES URL routing
Tons of 3rd party modules
Drop-in security system
Sweet REST web service support
If you run into issues or just have questions, please jump on our Ortus Community and our Slack team and ask away.
ColdBox is Professional Open Source under the Apache 2.0 license. We'd love to have your help with the product.
ColdBox 6.0.0 is a major release for the ColdBox HMVC platform. It has some dramatic new features as we keep pushing for more modern and sustainable approaches to web development. We break down the major areas of development below and you can also find the full release notes per library at the end.
It is also yet another source code reduction due to the dropping of support for the following CFML Engines:
Adobe ColdFusion 11
Lucee 4.5
The info-graphic above shows you the supported engines the 6.x platform will support.
Thanks to our new futures approach, all major internal libraries (WireBox, CacheBox, LogBox, MVC) will leverage them for different tasks that require asynchronicity and scheduling. You will see a noticeble difference especially in the following areas:
Cache Reaping: All cache reaping is now done via a scheduled task running on specific frequencies
File Appenders: It uses an async schedule to stream log data to files instead of blocking operations for sending logs. It will use a logging in-memory queue to stream the log data to the file. So you can potentially send 10000 log events and eventually they will be streamed to disk.
A ColdBox future is used for async/parallel programming where you can register a task or multiple tasks that will execute in a non-blocking approach and trigger dependent computations which could also be asynchronous. This Future object can then be used to monitor the execution of the task and create rich completion/combining pipelines upon the results of such tasks. You can still use a get()
blocking operation, but that is an over simplistic approach to async programming because you are ultimately blocking to get the result.
ColdBox futures are backed by Java's CompletableFuture
API, so the majority of things will apply as well; even Java developers will feel at home. It will allow you to create rich pipelines for creating multiple Futures, chaining, composing and combining results.
This new approach to creating async pipelines and parallel processing, will further create extensibility and robustness in your ColdBox applications.
coldbox-tasks
Global ExecutorColdBox apps by default register a coldbox-tasks
fixed executor (20 threads - IO bound) that is used internally for cleanups, tasks, and schedules. However, any module or application can leverage it for scheduling tasks or workers.
CacheBox has been refactored to leverage the async facilities in ColdBox to schedule cache reaps instead of a request initiating the reaps. This brings a lot more stability and consistency to the reaping of caches as they all execute within the new ColdBox coldbox-tasks
schedule task executor.
If you are in CacheBox standalone mode, then the task scheduler will be called cachebox-tasks
.
LogBox has been entirely rewritten in script and a more fluent programming approach. It has also been revamped to leverage the scheduling executors and async programming aspects of our async package. All loggers now sport logging via an async queue and it is completely non-blocking. If you do heavy logging, the performance will be substantial.
The ModuleService
and all internal ColdBox services have deeper logging constructs and more information logging to understand what happens inside of the core.
Thanks to Eric Peterson, we have included Whoops as part of our core exception handling template. All the new application templates come pre-configured with whoops as part of the development
custom error template.
Warning: Make sure you DO NOT choose this template on production as it can expose code. We do our best to use environment detection to NEVER render it in production, but things can always happen. So always use it within the development
method.
This exception template will help you visualize and navigate your exceptions so you can fix those pesky bugs 🐞. You can even configure it to open the files directly into your favorite IDE using the coldbox.exceptionEditor
setting:
Valid Exception Editors are:
vscode
(Default)
vscode-insiders
sublime
textmate
emacs
macvim
idea
atom
espresso
After many years of adding a base handler and a response object to our application templates, we finally have integrated them into the core so developers can have even more support when building RESTFul services. This new rest handler will provide you with tons of utilities and approaches to make all of your RESTFul services:
Uniform
Consistent
A consistent and extensible response object
Error handling
Invalid Route handling
Much more
New base class coldbox.system.RestHandler
which you can inherit from or use our new restHandler
annotation. This will give you access to our enhanced API utilities and the native response object via the request context's getResponse()
method.
You can now build all of your api’s using the native response object like the rest templates, but now from the core directly. This Rest Handler gives you the following actions out of the box:
The aroundHandler
() provided in the RestHandler
will intercept all rest calls in order to provide consistency and uniformity to all your actions. It will try/catch for major known exceptions, time your requests, add extra output on development and much more. Here are a list of the features available to you:
Exception Handling
Automatic trapping of the following exceptions: InvalidCredentials, ValidationException, EntityNotFound, RecordNotFound
Automatic trapping of other exceptions
Logging automatically the exception with extra restful metadata
If in a development
environment it will respond with much more information necessary for debugging both in the response object and headers
Development Responses
If you are in a development
environment it will set the following headers for you:
x-current-route
x-current-routed-url
x-current-routed-namespace
x-current-event
Global Headers
The following headers are sent in each request
x-response-time
: The time the request took in CF
x-cached-response
: If the request is cached via event caching
The aroundHandler()
is also smart in detecting the following outputs from a handler:
Handler return
results
Setting a view or layout to render
Explicit renderData()
calls
getResponse()
Will get you the current prc.response
object, if the object doesn’t exist, it will create it and set it for you
The core response object can be found here: coldbox.system.web.context.Response
If you would like to extend or modify the behavior of the core RestHandler
then you will have to create your own base handler that inherits from it. Then all of your concrete handlers will inherit from your very own handler.
The response object can be found here: coldbox.system.web.context.Response
and the rest handler constructs it by calling the request context’s getResponse
() method. The method verifies if there is a prc.response
object and if it exists it returns it, else it creates a new one. So if you would like to use your very own, then just make sure that before the request you place your own response object in the prc
scope.
Here is a simple example using a preProcess()
interceptor. Create a simple interceptor with commandbox e.g
and add the following method:
Don't forget to register your interceptor in config/Coldbox.cfc:
That’s it. Once that response object is in the prc
scope, ColdBox will utilize it. Just make sure that your custom Response object satisfies the methods in the core one. If you want to modify the output of the response object a good place to do that would be in the getDataPacket()
method of your own MyResponseObject
. Just make sure this method will return a struct
.
when()
Our super type now includes a new when()
method that will allow you to build functional statements within your handlers. Here is the signature of this functional helper:
The target
is a boolean and can be an expression that evaluates to a boolean. If the target
is true, then the success
closure will be executed for you, if not, the failure
closure will be executed.
The entire rendering mechanisms have changed in ColdBox 6 and we now support a singleton based approach to view rendering. It still allows for variable safety, but the way renderings in ColdBox 6 are done are orders of magnitude faster than pre ColdBox 6 days. If you are using applications like ContentBox or Preside CMS or applications with tons of renderView()
calls, your applications will fly now!
Thanks to a community pull request you now have the ability to chose the reinit key instead of the default of fwReinit
. This is useful for security purposes.
Then you can use it in the request: http://localhost/index.cfm?cbReinit=true
If you are using LogBox in standalone mode, you can now construct it by passing the path to your LogBox configuration file or no path at all and we will construct LogBox with our new default config file to stream logs to the console.
These methods have been deprecated in favor of our new announce()
method. We have also deprecated the argument interceptData
in favor of just data.
listen()
method to register one-off closuresHave you ever wanted to dynamically listen to events but not create CFC to enclose the method? Well, now you can use the new listen()
method which accepts a closure/udf so you can listen to ColdBox interceptions. Here is the method signature:
This allows you to easily register dynamic closures/udfs whenever you like so they can listen to events:
onColdBoxShutdown()
We have created a new interception point that is fired before ColdBox is shutdown completely. This can come from a reinit or an application expiration. This is a great place to shutdown custom executors, or messaging queues like RabbitMQ.
We have done several enhancements to the entire routing capabilities in ColdBox apart from several bug fixes.
buildLink()
Ease of UseWe have also re-arranged the arguments so you can easily build links with query strings using positional arguments instead of name-value pairs:
buildLink()
Named Route SupportThe request context method event.buildLink()
has been now added named route support. The event.route()
method was introduced to do named routing with a name
and params
argument. Now, you can also use this approach but via the to
argument in the buildLink()
method by just passing a struct.
You can now add custom metadata to specific route or resourceful routes by using the meta()
method or the meta
argument. This is simply a struct of name value pairs you can add into the route record.
Now, how good is adding the metadata if you can't get it. So you can get the current route's metadata via the new request context method: getCurrentRouteMeta()
method:
We have also added the method getCurrentRouteRecord()
to the request context so you can get the struct definition of the route record of the currently routed route. Below is a sample screenshot of the record:
The toRedirect()
method has been enhanced to accept a closure as the target
of relocation. This closure will received the parsed parameters, the incoming route record and the event object. You can now determine dynamically where the relocation will go.
This is great if you need to actually parse the incoming route and do a dynamic relocation.
Happy Redirecting!
The full release notes per library can be found below. Just click on the library tab and explore their release notes:
Info : We would recommend you create a
config/CacheBox.cfc
and put all your caching configuration there instead of in the main ColdBox configuration file. This will give you further portability and decoupling.
An absolute or relative path to the CacheBox configuration CFC or XML file to use instead of declaring the rest of the keys in this structure. So if you do not define a cacheBox structure, the framework will look for the default value: config/CacheBox.cfc
and it will load it if found. If not found, it will use the default CacheBox configuration found in /coldbox/system/web/config/CacheBox.cfc
A structure that enables scope registration of the CacheBox factory in either server, cluster, application or session scope.
The configuration of the default cache which will have an implicit name of default which is a reserved cache name. It also has a default provider of CacheBox which cannot be changed.
A structure where you can create more named caches for usage in your CacheBox factory.
AdvancedScript (default
): A script based advanced template
rest: A RESTFul services template
rest-hmvc: A RESTFul service built with modules
Simple : A traditional simple template
SuperSimple : The bare-bones template
So let's create our first app using the default template skeleton AdvancedScript:
This will scaffold the application and also install ColdBox for you. The following folders/files are generated for you:
Now let's start a server so we can see our application running:
This command will start a server with URL rewrites enabled, open a web browser for you and execute the index.cfm
which in turn executes the default event by convention in a ColdBox application: main.index
. This is now our first convention!
Tip: ColdBox Events map to handlers (cfc) and appropriate actions (functions)
Tip: The default event can be also changed in the configuration file: config/Coldbox.cfc
Hooray, we have scaffolded our first application, started a server and executed the default event. Explore the application template generated, as it contains many useful information about your application.
Tip: Type coldbox create app help
to get help on all the options for creating ColdBox applications.
What is the common denominator in all the conventions? That they are all optional.
Nothing is really mandatory in ColdBox anymore.
There will be times when you make configuration or code changes that are not reflected immediately in the application due to caching. You can tell the framework to reinit or restart the application for you via the URL by leveraging the special URL variable fwreinit
.
You can also use CommandBox to reinit the application:
The basic configuration object has 1 method for application configuration called configure()
where you will place all your configuration directives and settings:
Inside of this configuration method you will place several core and third-party configuration structures that can alter your application settings and behavior. Below are the core directives you can define:
This element defines custom conventions for your application. By default, the framework has a default set of conventions that you need to adhere too. However, if you would like to implement your own conventions for a specific application, you can use this setting, otherwise do not declare it:
The ColdBox directive is where you configure the framework for operation.
Info : Please note that there are no mandatory settings as of ColdBox 4.2.0. If fact, you can remove the config file completely and your app will run. It will be impossible to reinit the app however without a reinit password set.
Protect the reinitialization of the framework URL actions. For security, if this setting is omitted, we will create a random password. Setting it to an empty string will allow you to reinitialize without a password. Always have a password set for public-facing sites.
The key used in FORM or URL to reinit the framework. The default is fwreinit
but you can change it to whatever you like.
Will scan the conventions directory for new handler CFCs on each request if activated. Use false for production, this is only a development true setting.
These settings map 1-1 from ColdBox events to the Application.cfc
life-cycle methods. The only one that is not is the defaultEvent
, which selects what event the framework will execute when no incoming event is detected via URL/FORM or REMOTE executions.
The ColdBox extension points are a great way to create federated applications that can reuse a centralized core instead of the local conventions. It is also a great way to extend some core classes with your own.
A list or array of absolute or relative paths to a UDF helper file. The framework will load all the methods found in this helper file globally. Meaning it will be injected in ALL handlers, layouts and views.
A list or array of absolute or relative paths to a UDF helper file. The framework will load all the methods found in this helper in layouts and views only.
A list or array of locations of where ColdBox should look for modules to load into your application. The path can be a cf mapping or cfinclude
compatible location. Modules are searched and loaded in the order of the declared locations. The first location ColdBox will search for modules is the conventions folder modules
The CF include path of where to look for secondary views for your application. Secondary views look just like normal views except the framework looks in the conventions folder first and if not found then searches this location.
The CF include path of where to look for secondary layouts for your application. Secondary layouts look just like normal layouts except the framework looks in the conventions folder first and if not found then searches this location.
The CF dot notation path of where to look for secondary events for your application. Secondary events look just like normal events except the framework looks in the conventions folder first and if not found then searches this location.
The CF dot notation path of the CFC that will decorate the system Request Context object.
The CF dot notation path of the CFC that will decorate the system Controller
The event handler to call whenever ANY non-catched exception occurs anywhere in the request lifecycle execution. Before this event is fired, the framework will log the error and place the exception in the prc as prc.exception
.
The event handler to call whenever a route or event is accessed with an invalid HTTP method.
This is the event handler that will fire masking a non-existent event that gets requested. This is a great place to place 302 or 404 redirects whenever non-existent events are being requested.
The relative path from the application's root level of where the custom error template exists. This template receives a key in the private request collection called exception
that contains the exception. By default ColdBox does not show robust exceptions, you can turn on robust exceptions by choosing the following template:
ColdBox by convention can talk to, use and inject models from the models
folder by just using their name. On startup it will scan your entire models
folder and will register all the discovered models. This setting is true by default.
By default implicit views are case sensitive since ColdBox version 5.2.0, before this version the default was false.
This directive tells ColdBox that when events are executed they will be inspected for caching metadata. This does not mean that ALL events WILL be cached if this setting is turned on. It just activates the inspection mechanisms for whenever you annotate events for caching or using the runEvent()
caching methods.
This is useful to be set to false in development and true in production. This tells the framework to cache your event handler objects as singletons.
Allows you to use implicit views in your application and view dispatching. You can get a performance boost if you disable this setting.
This setting allows you to configure a lambda/closure that will return back the user's request identifier according to your own algorithms. This overrides the internal way ColdBox identifies requests incoming to the application which are used internally to track sessions, flash rams, etc.
The discovery algorithm we use is the following:
If we have an identifierProvider
closure/lambda/udf, then call it and use the return value
If we have sessions enabled, use the jessionId
or session URL Token
If we have cookies enabled, use the cfid/cftoken
If we have in the URL the cfid/cftoken
Create a request based tracking identifier: cbUserTrackingId
This is a boolean setting used when calling the ColdBox proxy's process()
method from a Flex or SOAP/REST call. If this setting is set to true, the proxy will return back to the remote call the entire request collection structure ALWAYS! If set to false, it will return, whatever the event handler returned back. Our best practice is to always have this false and return appropriate data back.
This directive tells ColdBox that when views are rendered, the cache=true
parameter will be obeyed. Turning on this setting will not cause any views to be cached unless you are also passing in the caching parameters to your renderView()
or event.setView()
calls.
Get up and running with ColdBox easily.
Welcome to the world of ColdBox!
We are excited you are taking this development journey with us. Before we get started with ColdBox let's install CommandBox CLI, which will allow you to install/uninstall dependencies, start servers, have a REPL tool and much more.
ColdBox has the following supported IDE Tools:
Note : However, you can use your own ColdFusion server setup as you see fit. We use CommandBox as everything is scriptable and fast!
No Java Runtime (80mb)
Embedded Runtime (120mb)
Once you download and expand CommandBox you will have the box.exe
or box
binary, which you can place in your Windows Path or *Unix /usr/bin
folder to have it available system wide. Then just open the binary and CommandBox will unpack itself your user's directory: {User}/.CommandBox
. This happens only once and the next thing you know, you are in the CommandBox interactive shell!
We will be able to execute a-la-carte commands from our command line or go into the interactive shell for multiple commands. We recommend the interactive shell as it is faster and can remain open in your project root.
All examples in this book are based on the fact of having an interactive shell open.
To get started open the CommandBox binary or enter the shell by typing box
in your terminal or console. Then let's create a new folder and install ColdBox into a directory.
You can also install the latest bleeding edge version by using the coldbox@be
slug instead, or any previous version.
That's it! CommandBox can now track this version of ColdBox for you in this directory.
AdvancedScript (default
): A script based advanced template
elixir : A ColdBox Elixir based template
ElixirBower : A ColdBox Elixir + Bower based template
ElixirVueJS : A ColdBox Elixir + Vue.js based template
rest: A RESTFul services template
rest-hmvc: A RESTFul service built with modules
Simple : A traditional simple template
SuperSimple : The bare-bones template
Type coldbox create app
help in CommandBox to get tons of help for scaffolding apps.
To uninstall ColdBox from this application folder just type uninstall coldbox
.
To update ColdBox from a previous version, just type update coldbox
.
This structure configures the interceptor service in your application.
throwOnInvalidStates
This tells the interceptor service to throw an exception if the state announced for interception is not valid or does not exist. Defaults to false.
customInterceptionPoints
This key is a comma delimited list or an array of custom interception points you will be registering for custom announcements in your application. This is the way to provide an observer-observable pattern to your applications.
We have done a tremendous amount of work to expose all the async and parallel programming constructs in ColdBox to the entire framework so developers can leverage them. There is just so much we have done on this release for concurrency, task scheduling, and parallel programming to include in one page. So visit our section to start delving into what we are lovingly calling cbFutures!
See
[] - CacheBox creates multiple reap threads if the initial one take longer to complete than the reap frequency
[] - Error in AbstractFlashScope: key does't exists due to race conditions
[] - InvalidEvent is not working when set to a module event
[] - Stopgap for Lucee bug losing sessionCluster application setting
[] - toResponse() silently fails on incorrect data types
[] - Unable to manually call invalid event method without producing error
[] - Router method and argument name discrepancy
[] - Capture request before announcing onRequestCapture
[] - XML Converter Updated invoke() to correctly call method by name
[] - ElixirPath does not take in account of module root
[] - Self-autowire fails for applications with context root configured in ColdBox Proxy
[] - when passing custom cfml executors to futures it blows up as the native executor is not set
[] - NullPointerException in ScheduledExecutor (Lucee 5.3.4.80)
[] - PopulateFromQuery : Gracefully handle out of index rownumber in populateFromQuery #450
[] - ColdBox 6 blows up if models directory doesn't exist
[] - Reinit-Password-Check does not use the new "reinitKey"-Setting
[] - ViewHelpers not working in CB-6 RC
[] - Pagination not showing from rest response
[] - RendererEncapsulator passes view-variables to "next" rendered view
[] - Whoops breaking on some exceptions
[] - Template cache eventSnippets don't match module events or event suffixes
[] - queryString argument ignored when using event in `BaseTestCase#execute`
[] - Renderer.ViewNotSetException when renderLayout used in request
[] - Garbled text in Whoops error screen - utf8 encoding
[] - Async Workers
[] - Performance: make renderer a singleton
[] - Improve the bug reporting template for development based on whoops
[] - Incorporate Response and RestHandler into core
[] - All ColdBox apps get a `coldbox-tasks` scheduler executor for internal ColdBox services and scheduled tasks
[] - Updated the default ColdBox config appender to be to console instead of the dummy one
[] - ColdBox controller gets a reference to the AsyncManager and registers a new `AsyncManager@coldbox` wirebox mapping
[] - Allow for the application to declare it's executors via the new `executors` configuration element
[] - Allow for a module to declare it's executors via the new `executors` configuration element
[] - Introduction of async/parallel programming via cbPromises
[] - ability to do async scheduled tasks with new async cbpromises
[] - Convert proxy to script and optimize it
[] - Add setting to define reinit key vs. hard-coded fwreinit: reinitKey
[] - jsonPayloadToRC now defaults to true
[] - autoMapModels defaults to true now
[] - RequestContext Add urlMatches to match current urls
[] - Response, SuperType => New functional if construct when( boolean, success, failure )
[] - Removed fwsetting argument from getSetting() in favor of a new function: getColdBoxSetting()
[] - BaseTestCase new method getHandlerResults() to easy get the handler results, also injected into test request contexts
[] - New dsl coldbox:coldboxSettings alias to coldbox:fwSettings
[] - New dsl coldbox:asyncManager to get the async manager
[] - Elixir manifest support for module and app roots via discovery
[] - New listen() super type and interceptor service method to register one-off closures on specific interception points
[] - The buildLink( to ) argument can now be a struct to support named routes : { name, params }
[] - Move queryString as the second argument for buildLink() so you can use it with psoitional params
[] - New context method: getCurrentRouteRecord() which gives you the full routed route record
[] - New context method: getCurrentRouteMeta() which gives you the routed route metadata if any
[] - New router method: meta() that you can use to store metadata for a specific route
[] - Every route record can now store a struct of metadata alongside of it using the `meta` key
[] - Allow toRedirect() to accept a closure which receives the matched route, you can process and then return the redirect location
[] - New onColdBoxShutdown interception point fired when the entire framework app is going down
[] - onInvalidEvent is now removed in favor of invalidEventHandler, this was deprecated in 5.x
[] - Removed interceptors.SES as it was deprecated in 5
[] - setnextEvent removed as it was deprecated in 5
[] - getModel() is now fully deprecated and removed in fvor of getInstance()
[] - elixir version 2 support removed
[] - `request` and associated integration test methods are not in the official docs
[] - Update cachebox flash ram to standardize on unique key discovery
[] - Improvements to threading for interceptors and logging to avoid dumb Adobe duplicates
[] - Change announceInterception() and processState() to a single method name like: announce()
[] - Use relocate and setNextEvent status codes in getStatusCode for testing integration
[] - Deprecate interceptData in favor of just data
[] - Please add an easily accessible "fwreinit" button to whoops...
[] - migrating usage of cgi.http_host to cgi.server_name due to inconsistencies with proxy requests that affects caching and many other features
[] - Interceptor Buffer Methods Removed
[] - Better module registration/activation logging to identify location and version
[] - Fix constructor injection with virtual inheritance
[] - Injector's get a reference to an asyncManager and a task scheduler whether they are in ColdBox or non-ColdBox mode
[] - New `executors` dsl so you can easily inject executors ANYWEHRE
[] - New dsl coldbox:coldboxSetting:{setting} alias to coldbox:fwSetting:{setting}
[] - Improve WireBox error on Adobe CF
[] - Rename WireBox provider get() to $get() to avoid conflicts with provided classes
[] - getInstance() now accepts either dsl or name via the first argument and initArguments as second argument
[] - Announced Events in the set() of the cacheBoxProvider
[] - cfthread-20506;variable [ATTRIBUES] doesn't exist;lucee.runtime.exp.ExpressionException: variable [ATTRIBUES] doesn't exist
[] - CacheBox reaper : migrate to a scheduled task via cbPromises
[] - CacheFactory gets a reference to an asyncManager and a task scheduler whether they are in ColdBox or non-ColdBox mode
[] - Migrations to script and more fluent programming
[] - FileAppender: if logging happens in a thread, queue never gets processed and, potentially, you run out of heap space
[] - Rotate property is defined but never used
[] - Work around for adobe bug CF-4204874 where closures are holding on to tak contexts
[] - Rolling file appender inserting tabs on first line
[] - Allow config path as string in LogBox init (standalone)
[] - Allow standard appenders to be configured by name (instead of full path)
[] - Added an `err()` to abstract appenders for reporting to the error streams
[] - All appenders get a reference to the running LogBox instance
[] - LogBox has a scheduler executor and the asyncmanager attached to it for standalone and ColdBox mode.
[] - Rolling appender now uses the new async schedulers to stream data to files
[] - Update ConsoleAppender to use TaskScheduler
[] - AbstractAppender log listener and queueing facilities are now available for all appenders
[] - DB Appender now uses a queueing approach to sending log messages
[] - Rolling File Appender now uses the async scheduler for log rotation checks
[] - Improvements to threading for logging to avoid dumb Adobe duplicates
[] - refactoring of internal utility closures to udfs to avoid ACF memory leaks: CF-4204874
[] - Migrations to script and more fluent programming
The CacheBox structure is based on the , and it allows you to customize the caches in your application. Below are the main keys you can fill out, but we recommend you review the CacheBox documentation for further detail.
CommandBox comes with a coldbox create app
command that can enable you to create application skeletons using one of our official skeletons or . Here are the names of the common ones you can find in our Github Organization:
elixir : A based template
ElixirBower : A + Bower based template
ElixirVueJS : A + Vue.js based template
You can find all our template skeletons here:
This will start up a 5 open source CFML engine. If you would like an Adobe ColdFusion server then just add to the command: cfengine=adobe@{version}
where {version}
can be: 2021,2018,2016.
Instead of executing pages like in a traditional application, we always execute the same page but distinguish the event we want via . When no mappings are present we execute the default event by convention.
ColdBox is a conventions based framework, meaning you don't have to explicitly write everything. We have a few contracts in place that you must follow and boom, things happen. The location and names of files and functions matter. Since we scaffolded our first application, let's write down in a table below with the different conventions that exist in ColdBox.
Tip: You can add a password to the reinit procedures for further security, please see the .
Sublime -
VSCode -
CFBuilder -
The first step in our journey is to CommandBox. is a ColdFusion (CFML) Command Line Interface (CLI), REPL, Package Manager and Embedded Server. We will be using CommandBox for almost every excercise in this book and it will also allow you to get up and running with ColdFusion and ColdBox in a much speedier manner.
You can download CommandBox from the official site: and install in your preferred Operating System (Windows, Mac, *unix). CommandBox comes in two flavors:
So make sure you choose your desired installation path and follow the instructions here:
CommandBox will resolve coldbox
from FORGEBOX (), use the latest version available, download and install it in this folder alongside a box.json
file which represents your application package.
CommandBox comes with a coldbox create app
command that can enable you to create application skeletons using one of our official skeletons or by creating application template:
You can find many scaffolding templates for ColdBox in our Github organization:
Info Please see the section for more information.