Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
CommandBox comes with a coldbox create app command that can enable you to create application skeletons using one of our official skeletons or your own. Here are the names of the common ones you can find in our Github Organization:
AdvancedScript (default): A script based advanced template
elixir : A ColdBox Elixir based template
ElixirBower : A + Bower based template
ElixirVueJS : A + 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
You can find all our template skeletons here:
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!
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.
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.
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.
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:
Tip: You can add a password to the reinit procedures for further security, please see the .
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 )
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.
any function index( event, rc, prc ){
return contactService.getAll();
}any function index( event, rc, prc ){
prc.aContacts = contactService.getAll();
event.renderData( data=prc.aContacts, formats="xml,json,pdf,html" );
}event.renderData( data=prc.aContacts, formats="xml,json,pdf,html" );# Default: The view is presented using no extension or html,cfm
http://localhost:{port}/contacts/index
http://localhost:{port}/contacts/index.html
http://localhost:{port}/contacts/index.cfm
# JSON output
http://localhost:{port}/contacts/index.json
# OR Accepts: application/json
# XML output
http://localhost:{port}/contacts/index.xml
# OR Accepts: application/xml
# PDF output
http://localhost:{port}/contacts/index.pdf
# OR Accepts: application/pdf
// Restuful Route
route(
pattern="/api/contacts",
target="contacts.index",
name="api.contacts"
);
// Default Route
route( ":handler/:action?" ).end();http://localhost:{port}/api/contacts.jsonLayouts
models
false
Model layer business objects
modules
false
CommandBox Tracked Modules
modules_app
false
Custom Modules You Write
tests
false
A test harness with runners, specs and more.
views
false
Views
File/Folder Convention
Mandatory
Description
config/Coldbox.cfc
false
The application configuration file
config/Router.cfc
false
The application URL router
handlers
false
Event Handlers (controllers)
layouts

false
coldbox create app Quickstart+ coldbox // The ColdBox framework library (CommandBox Tracked)
+ config // Configuration files
+ handlers // Your handlers/controllers
+ includes // static assets
+ interceptors // global interceptors
+ layouts // Your layouts
+ lib // Java Jars to load
+ models // Your Models
+ modules // CommandBox Tracked Modules
+ modules_app // Custom modules
+ tests // Test harness
+ views // Your Views
+ Application.cfc // Bootstrap
+ box.json // CommandBox package descriptor
+ index.cfm // Front controllerserver starthttp://localhost:{port}/?fwreinit=1coldbox reinitA 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 . We will show you how in the .
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:
Now let's create our first controller, which in ColdBox is called Event Handler. Let's go to CommandBox again:
This will generate the following files:
A new handler called hello.cfc inside of the handlers folder
A view called index.cfm in the views/hello folder
An integration test at tests/specs/integration/helloTest.cfc.
Now go to your browser and enter the following URL to execute the generated event:
You will now see a big hello.index outputted to the screen. You have now created your first handler and view combination. However, how did this work? It works as ColdBox by convention creates another agreement with you on how to execute events, default URL routing.
Your application router is located at : config/Router.cfc. It will include a few default routes for you and the following default URL route:
This route tells ColdBox to look for the names of handlers (including directory names) and for names of the handler actions (functions). The ? on the :action portion denotes that the action might or might not exist in the URL. If it doesn't exist, then another convention is in play, the default action which is index.
Let's check out the handler code:
As you can see, a handler is a simple CFC with functions on them. Each function maps to an action that is executed via the URL. The default action in ColdBox is index()which receives three arguments:
event - An object that represents the request and can modify the response. We call this object the .
rc - A struct that contains both URL/FORM variables (unsafe data)
prc - A secondary struct that is
Tip: The view is not rendered in line 7, but rendered after the execution of the action by the framework.
Did you detect a convention here?
The sections in the URL are the same as the name of the event handler CFC (hello.cfc) and method that was generated index(). By convention, this is how you execute events in ColdBox by leveraging the following URL pattern that matches the name of a handler and action function.
Tip : You can also nest handlers into folders and you can also pass the name of the folder(s) as well.
If no action is defined in the URL then the default action of index will be used.
All of this URL magic happens thanks to the URL mappings capabilities in ColdBox. By convention, you can write beautiful URLs that are RESTFul and by convention. You can also extend them and create more expressive URL Mappings by leveraging the config/Router.cfc which is your application router.
Tip: Please see the guide for more in-depth information.
Now let's create a virtual event, which is basically just a view we want to execute with no event handler controller needed. This is a great way to incorporate non-mvc files into ColdBox. Migrating from a traditional application?
Open the view now (/views/virtual/hello.cfm) and add the following:
Then go execute the virtual event:
You will get the Hello From ColdBox Land! displayed! This is a great way to create tests or even bring in legacy/procedural templates into an MVC framework.
Tip: You can see our section for more in-depth information.
coldbox create handler name="hello" actions="index"# With rewrites enabled
http://localhost:{port}/hello/index// Conventions based routing
route( ":handler/:action?" ).end();component{
/**
* Default Action
*/
function index( event, rc, prc ){
event.setView( "hello/index" );
}
}http://localhost:{port}/folder/handler/action
http://localhost:{port}/handler/action
http://localhost:{port}/handlercoldbox create view name="virtual/hello"<h1>Hello from ColdBox Land!</h1>http://localhost:{port}/virtual/helloCongratulations! Did you finish this guide in less than 60 minutes? If you did please leave us some great feedback below. If you didn't, then please do tell us why, we would love to improve our guides.
You can now move on to the next level in becoming a ColdBox Guru! Choose your path below:
If you run into issues or just have questions, please jump on our and our and ask away.
ColdBox is Professional Open Source under the Apache 2.0 license. We'd love to have your help with the product.
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.
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.
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 , which models the incoming request and even contains all of your incoming FORM and URL variables in a structure called rc.
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.
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 ).
<div id="maincontent">
#renderView()#
</div># Create a Funky layout
coldbox create layout name="Funky"
# Create a footer
coldbox create view name="main/footer"<h1>funky Layout</h1>
<cfoutput>#renderView()#</cfoutput>
<hr>
<cfoutput>#renderView( "main/footer" )#</cfoutput>function index( event, rc, prc ){
// param an incoming variable.
event.paramValue( "name", "nobody" );
// set a private variable
prc.when = dateFormat( now(), "full" );
// set the view to render with our new layout
event.setView( view="hello/index", layout="Funky" );
}/**
* Builds links to events or URL Routes
*
* @to The event or route path you want to create the link to
* @queryString The query string to append which can be a regular query string string, or a struct of name-value pairs
* @translate Translate between . to / depending on the SES mode on to and queryString arguments. Defaults to true.
* @ssl Turn SSl on/off on URL creation, by default is SSL is enabled, we will use it.
* @baseURL If not using SES, you can use this argument to create your own base url apart from the default of index.cfm. Example: https://mysample.com/index.cfm
*/
string function buildLink(
to,
queryString = "",
boolean translate = true,
boolean ssl,
baseURL = ""
){<cfoutput>
<h1>Hello from ColdBox Land!</h1>
<p><a href="#event.buildLink( "main" )#">Go home</a></p>
</cfoutput><form action="#event.buildLink( 'user.save' )#" method="post">
...
</form>Event handlers are the controller layer in ColdBox and is what you will be executing via the URLor a FORMpost. 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 .
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.
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() () 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 section for in-depth information about them.
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:
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 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: 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:
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.
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 (), use the latest version available, download and install it in this folder alongside a box.json file which represents your application package.
CommandBox can now track this version of ColdBox for you in this directory. In the we will scaffold a ColdBox application using an application template.
You can find many scaffolding templates for ColdBox in our Github organization:
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.
/**
* Development environment
*/
function development() {
coldbox.customErrorTemplate = "/coldbox/system/exceptions/Whoops.cfm"; // interactive bug report
coldbox.handlerCaching = false;
coldbox.handlersIndexAutoReload = true;
coldbox.eventCaching = false;
coldbox.viewCaching = false;
}component extends="coldbox.system.EventHandler" {
/**
* Default Action
*/
function index( event, rc, prc ) {
prc.welcomeMessage = "Welcome to ColdBox!";
event.setView( "main/index" );
}
/**
* Produce some restfulf data
*/
function data( event, rc, prc ) {
return [
{ "id" : createUUID(), name : "Luis" },
{ "id" : createUUID(), name : "JOe" },
{ "id" : createUUID(), name : "Bob" },
{ "id" : createUUID(), name : "Darth" }
];
}
/**
* Relocation example
*/
function doSomething( event, rc, prc ) {
relocate( "main.index" );
}
/************************************** IMPLICIT ACTIONS *********************************************/
function onAppInit( event, rc, prc ) {
}
function onRequestStart( event, rc, prc ) {
}
function onRequestEnd( event, rc, prc ) {
}
function onSessionStart( event, rc, prc ) {
}
function onSessionEnd( event, rc, prc ) {
var sessionScope = event.getValue( "sessionReference" );
var applicationScope = event.getValue( "applicationReference" );
}
function onException( event, rc, prc ) {
event.setHTTPHeader( statusCode = 500 );
// Grab Exception From private request collection, placed by ColdBox Exception Handling
var exception = prc.exception;
// Place exception handler below:
}
}http://localhost:{port}/folder/handler/action
http://localhost:{port}/handler/action
http://localhost:{port}/handlerfunction index( event, rc, prc ){
// param an incoming variable.
event.paramValue( "name", "nobody" );
// set a private variable
prc.when = dateFormat( now(), "full" );
// set the view to render
event.setView( "hello/index" );
}<cfoutput>
<p>Hello #encodeForHTML( rc.name )#, today is #prc.when#</p>
</cfoutput>mkdir 60-minute-quickstart --cd
install coldboxDir 0 Jan 25,2021 11:04:05 coldbox
File 112 Jan 25,2021 11:04:05 box.json

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: . 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 variablesscope.
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 .
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.
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: []
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

coldbox create model name="ContactService" methods="getAll" persistence="singleton"/**
* I am a new Model Object
*/
component singleton accessors="true"{
// Properties
/**
* Constructor
*/
ContactService function init(){
return this;
}
/**
* getAll
*/
function getAll(){
}
}/**
* I am a new Model Object
*/
component singleton accessors="true"{
// Properties
property name="data" type="array";
/**
* Constructor
*/
ContactService function init(){
variables.data = [
{ "id"=1, "name"="coldbox" },
{ "id"=2, "name"="superman" },
{ "id"=3, "name"="batman" }
];
return this;
}
/**
* Get all the contacts
*/
function getAll(){
return variables.data;
}
}coldbox create handler name="contacts" actions="index"component{
property name="contactService" inject="ContactService";
any function index( event, rc, prc ){
event.setView( "contacts/index" );
}
}any function index( event, rc, prc ){
prc.aContacts = contactService.getAll();
event.setView( "contacts/index" );
}<cfoutput>
<h1>My Contacts</h1>
#html.table( data=prc.aContacts, class="table table-striped" )#
</cfoutput>

