My First ColdBox Application

Introduction

This quick guide will show you how to start off and create a running ColdBox application. You can generate it via ANT or do a simple copy/paste of the ColdBox application template or use the ColdBox dashboard to generate an application. I would recommend you at least read the ColdBox Overview guide before reading this guide.

How to start? Start off by copying the ApplicationTemplate folder to your web root and name it to something you want. Then, open the config/coldbox.xml.cfm file and adjust it to your liking. You can read the Config Guide in order to understand all the variables and settings in this file.

The easiest way to create new applications is by using the ColdBox Dashboard application generator or the included ANT build script build.xml. You can run it either in the command line or via Eclipse. This script is an application generator wizard. After this it will auto-generate the entire application for you and you can then just modify to your liking. Look below for a screenshot on how to run the build file from eclipse.

See cbDirectoryStructure, cbConfigGuide

The ColdBox ANT Application Generator

ANT Script: Generated Application

Extra Configuration

If you copied the directory and did not use the ANT script, then you need to change the name property of your Application.cfc template. So open the file Application.cfc and change the this.name property to whatever you want it to be. Remember that every application will need its own name property. Also, please note that ColdBox uses the session scope for some plugins and the application scope for the framework. So alter accordingly to what you need to do in your application, this is YOUR JOB.

See cbSystemRequirements

Open the provided event handler(s) in the template folder: main.cfc and general.cfc and modify them if you need to. I recommend you leave them as they are in order for you to see that the skeleton works.

Now that you have completed editing your configuration file, Application.cfc and your first event handler, you are ready to see results. Point your browser to your application folder and you will see a screen similar to the one below:

What Happened?

Well, before I actually go in and explain the code, you will have to do some reading first. This is necessary in order for you to understand what ColdBox is doing and how it is doing it. So read the following sections below if you would like to, if not continue in the next section:

Step 1: Configuring the Application

Below you can see the coldbox.xml that the application runs on, for more in depth detail please look at the Config Guide since the example below does not have all the elements an application can use.

<?xml version="1.0" encoding="UTF-8"?>
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:noNamespaceSchemaLocation="http://www.coldboxframework.com/schema/config_2.6.0.xsd">
        <Settings>
                <!--The name of your application.-->
                <Setting name="AppName"                                         value="MyFirstApp"/>
                <!-- ColdBox set-up information for J2EE installation.
                     As context-root are actually virtual locations which does not correspond to physical location of files. for example 
                     /openbd   /var/www/html/tomcat/deploy/bluedragon

                     AppMapping setting will adjust physical location of Project/App files and coldbox will load handlers,plugis,config file etc
                     Create a cf mapping and enable this value. 
                     /MyApp /var/www/html/tomcat/deploy/bluedragon/MyAppFolder
                
                If you are using a coldbox app to power flex/remote apps, you NEED to set the AppMapping also. In Summary,
                the AppMapping is either a CF mapping or the path from the webroot to this application root. If this setting
                is not set, then coldbox will try to auto-calculate it for you. Please read the docs.
                
                <Setting name="AppMapping"                                      value="/MyApp"/>      
                
                -->
                <!--Default Debugmode boolean flag (Set to false in production environments)-->
                <Setting name="DebugMode"                                       value="true" />
                <!--The Debug Password to use in order to activate/deactivate debugmode,activated by url actions -->
                <Setting name="DebugPassword"                           value=""/>
                <!--The fwreinit password to use in order to reinitialize the framework and application.Optional, else leave blank -->
                <Setting name="ReinitPassword"                          value=""/>
                <!--Default event name variable to use in URL/FORM etc. -->
                <Setting name="EventName"                                       value="event" />
                <!--This feature is enabled by default to permit the url dumpvar parameter-->
                <Setting name="EnableDumpVar"                           value="true" />
                <!--Log Errors and entries on the coldfusion server logs, disabled by default if not used-->
                <Setting name="EnableColdfusionLogging"         value="false" />
                <!--Log Errors and entries in ColdBox's own logging facilities. You choose the location, finally per application logging.-->
                <Setting name="EnableColdboxLogging"            value="true" />
                <!--The absolute or relative path to where you want to store your log files for this application-->
                <Setting name="ColdboxLogsLocation"                     value="logs" />
                <!--Default Event to run if no event is set or passed. Usually the event to be fired first (NOTE: use event handler syntax)-->
                <Setting name="DefaultEvent"                            value="general.index"/>
                <!--Event Handler to run on the start of a request, leave blank if not used. Emulates the Application.cfc onRequestStart method -->
                <Setting name="RequestStartHandler"             value="main.onRequestStart"/>
                <!--Event Handler to run at end of all requests, leave blank if not used. Emulates the Application.cfc onRequestEnd method-->
                <Setting name="RequestEndHandler"                       value=""/>
                <!--Event Handler to run at the start of an application, leave blank if not used. Emulates the Application.cfc onApplicationStart method        -->
                <Setting name="ApplicationStartHandler"         value="main.onAppInit"/>
                <!--Event Handler to run at the start of a session, leave blank if not used.-->
                <Setting name="SessionStartHandler"             value=""/>
                <!--Event Handler to run at the end of a session, leave blank if not used.-->
                <Setting name="SessionEndHandler"                       value=""/>
                <!--The event handler to execute on all framework exceptions. Event Handler syntax required.-->
                <Setting name="ExceptionHandler"                        value="" />
                <!--What event to fire when an invalid event is detected-->
                <Setting name="onInvalidEvent"                          value="" />
                <!--Full path from the application's root to your custom error page, else leave blank. -->
                <Setting name="CustomErrorTemplate"                     value="" />
                <!--The Email address from which all outgoing framework emails will be sent. -->
                <Setting name="OwnerEmail"                                      value="" />
                <!-- Enable Bug Reports to be emailed out, set to true by default if left blank
                        A sample template has been provided to you in includes/generic_error.cfm
                 -->
                <Setting name="EnableBugReports"                        value="false"/>
                <!--UDF Library To Load on every request for your views and handlers -->
                <Setting name="UDFLibraryFile"                          value="includes/helpers/ApplicationHelper.cfm" />
                <!--Messagebox Style Override. A boolean of wether to override the styles using your own css.-->
                <Setting name="MessageboxStyleOverride"         value="" />
                <!--Flag to Auto reload the internal handlers directory listing. False for production. -->
                <Setting name="HandlersIndexAutoReload"         value="true" />
                <!--Flag to auto reload the config.xml settings. False for production. -->
                <Setting name="ConfigAutoReload"                value="false" />
                <!-- Declare the custom plugins base invocation path, if used. You have to use dot notation.Example: mymapping.myplugins        -->
                <Setting name="MyPluginsLocation"               value="" />
                <!-- Declare the external views location. It can be relative to this app or external. This in turn is used to do cfincludes. -->
                <Setting name="ViewsExternalLocation"           value=""/>
                <!-- Declare the external handlers base invocation path, if used. You have to use dot notation.Example: mymapping.myhandlers    -->
                <Setting name="HandlersExternalLocation"        value="" />
                <!-- Declare the external models base invocation path, if used. You have to use dot notation.Example: mymapping.mymodels        -->
                <Setting name="ModelsExternalLocation"          value="" />
                <!--Flag to cache handlers. Default if left blank is true. -->
                <Setting name="HandlerCaching"                          value="false"/>
                <!--Flag to cache events if metadata declared. Default is true -->
                <Setting name="EventCaching"                            value="false"/>
                <!--IOC Framework if Used, else leave blank-->
                <Setting name="IOCFramework"                            value="" />
                <!--IOC Definition File Path, relative or absolute -->
                <Setting name="IOCDefinitionFile"                       value="" />
                <!--IOC Object Caching, true/false. For ColdBox to cache your IoC beans-->
                <Setting name="IOCObjectCaching"                        value="false" />
                <!--Request Context Decorator, leave blank if not using. Full instantiation path -->
                <Setting name="RequestContextDecorator"         value=""/>
                <!--Flag if the proxy returns the entire request collection or what the event handlers return, default is false -->
                <Setting name="ProxyReturnCollection"           value="false"/>
                <!-- What scope are flash persistance variables using. -->
                <Setting name="FlashURLPersistScope"            value="session"/>
        </Settings>

        <!-- Your Settings can go here, if not needed, use <YourSettings />. You can use these for anything you like.
                <YourSettings>
                        <Setting name="MySetting" value="My Value"/>
                        
                        whether to encrypt the values or not
                        <Setting name="cookiestorage_encryption" value="true"/>
                        
                        The encryption seed to use. Else, use a default one (Not Recommened)
                        <Setting name="cookiestorage_encryption_seed" value="mykey"/>
                        
                        The encryption algorithm to use (According to CFML Engine)
                        <Setting name="cookiestorage_encryption_algorithm" value="CFMX_COMPAT or BD_DEFAULT"/>
                        
                        Messagebox Plugin (You can now override the storage scope without affecting all framework applications)
                        <Setting name="messagebox_storage_scope" value="session or client" />
                        
                        Complex Settings follow JSON Syntax. www.json.org.  
                        *IMPORTANT: use single quotes in this xml file for JSON notation, ColdBox will translate it to double quotes.
                </YourSettings>
         -->
        <YourSettings>
                
        </YourSettings>
        
        <!-- Custom Conventions : You can override the framework wide conventions of the locations of the needed objects
        <Conventions>
                <handlersLocation></handlersLocation>
                <pluginsLocation></pluginsLocation>
                <layoutsLocation></layoutsLocation>
                <viewsLocation></viewsLocation>
                <eventAction></eventAction>     
                <modelsLocation></modelsLocation>       
        </Conventions>  
        -->
        
        <!--
        Control the ColdBox Debugger. The panels are self explanatory. The other settings are explained below.
        PersistentRequestProfiler : Activate the event profiler across multiple requests
        maxPersistentRequestProfilers : Max records to keep in the profiler. Don't get gready.
        maxRCPanelQueryRows : If a query is dumped in the RC panel, it will be truncated to this many rows.
        -->
        <DebuggerSettings>
                <PersistentRequestProfiler>true</PersistentRequestProfiler>
                <maxPersistentRequestProfilers>10</maxPersistentRequestProfilers>
                <maxRCPanelQueryRows>50</maxRCPanelQueryRows>
                
                <TracerPanel    show="true" expanded="true" />
                <InfoPanel              show="true" expanded="true" />
                <CachePanel     show="true" expanded="false" />
                <RCPanel                show="true" expanded="false" />
        </DebuggerSettings>     
        
        <!--Optional,if blank it will use the CFMX administrator settings.-->
        <MailServerSettings>
                <MailServer></MailServer>
                <MailPort></MailPort>
                <MailUsername></MailUsername>
                <MailPassword></MailPassword>
        </MailServerSettings>

        <!--Emails to Send bug reports, you can create as many as you like -->
        <BugTracerReports>
                <!-- <BugEmail>myemail@gmail.com</BugEmail> -->
        </BugTracerReports>
        
        <!--Webservice declarations your use in your application, if not use, leave blank
        Note that for the same webservice name you can have a development url and a production url.-->
        <WebServices>
                <!-- <WebService name="TESTWS1" URL="http://www.test.com/test1.cfc?wsdl" DevURL="http://dev.test.com/test1.cfc?wsdl" /> -->
                <!-- <WebService name="TESTWS2" URL="http://www.test.com/test2.cfc?wsdl" DevURL="http://dev.test.com/test2.cfc?wsdl" /> -->
        </WebServices>

        <!--Declare Layouts for your application here-->
        <Layouts>
                <!--Declare the default layout, MANDATORY-->
                <DefaultLayout>Layout.Main.cfm</DefaultLayout>
                
                <!--Default View, OPTIONAL
                <DefaultView>home</DefaultView>
                -->
                
                <!--
                Declare other layouts, with view/folder assignments if needed, else do not write them
                <Layout file="Layout.Popup.cfm" name="popup">
                        <View>vwTest</View>
                        <View>vwMyView</View>
                        <Folder>tags</Folder>
                </Layout>
                -->
        </Layouts>

        <!--Internationalization and resource Bundle setup:
        <i18N>
                <DefaultResourceBundle>includes/main</DefaultResourceBundle>
                <DefaultLocale>en_US</DefaultLocale>
                <LocaleStorage>session</LocaleStorage>
                <UknownTranslation></UknownTranslation>
        </i18N>
        -->
        <i18N />
        
        <!--Datasource Setup, you can then retreive a datasourceBean via the getDatasource("name") method: -->
        <Datasources>
                <!-- <Datasource alias="MyDSNAlias" name="real_dsn_name"   dbtype="mysql"  username="" password="" /> -->
        </Datasources>
        
        <!--ColdBox Object Caching Settings Overrides the Framework-wide settings -->
        <Cache>
                <ObjectDefaultTimeout>60</ObjectDefaultTimeout>
                <ObjectDefaultLastAccessTimeout>30</ObjectDefaultLastAccessTimeout>
                <UseLastAccessTimeouts>true</UseLastAccessTimeouts>
                <ReapFrequency>1</ReapFrequency>
                <MaxObjects>100</MaxObjects>
                <FreeMemoryPercentageThreshold>0</FreeMemoryPercentageThreshold>
                <EvictionPolicy>LRU</EvictionPolicy>
        </Cache>
        
        
        <!-- Interceptor Declarations 
        <Interceptors throwOnInvalidStates="true">
                <CustomInterceptionPoints>comma-delimited list</CustomInterceptionPoints>
                <Interceptor class="full class name">
                        <Property name="myProp">value</Property>
                        <Property name="myArray">[1,2,3]</Property>
                        <Property name="myStruct">{ key1:1, key2:2 }</Property>
                </Inteceptor>
                <Interceptor class="no property" />
        </Interceptors>
        -->
        
        <Interceptors>
                <!-- USE ENVIRONMENT CONTROL -->
                <Interceptor class="coldbox.system.interceptors.environmentControl">
                        <Property name='configFile'>config/environments.xml.cfm</Property>
                </Interceptor>
                <!-- USE AUTOWIRING -->
                <Interceptor class="coldbox.system.interceptors.autowire">
                        <Property name='enableSetterInjection'>true</Property>
                </Interceptor>
                <!-- USE SES -->
                <Interceptor class="coldbox.system.interceptors.ses">
                        <Property name="configFile">config/routes.cfm</Property>
                </Interceptor>          
                
        </Interceptors>
        
</Config>

Basically, there are a lot of configurations you can do for your application like adding datasources, internationalization, IoC (Coldspring|Lightwire) support etc. For this application we only care about a few configurations:

  • AppName : The name of your application.
  • DebugMode : To show or not the debugging panel (set to true in development)
  • DebugPassword : Set to blank for dev use (please remember to fill one up)
  • ReinitPassword : Set to blank for dev use (please remember to fill one up)
  • EnableColdboxLogging : Enables AOP logging for exceptions and information messages. (set to true)
  • ColdboxLogsLocation : Default location of the log files logs within your application
  • DefaultEvent : The event to fire when application starts up or there is no event defined. (set to ehGeneral.dspHello)
  • RequestStartHandler' : The event to fire at the beginning of every request. (set to ehMain.onRequestStart)
  • RequestEndHandler : The event to fire at the end of every request. (set to ehMain.onRequestEnd)
  • ApplicationStartHandler : The event to fire when application starts up. (set to ehMain.onAppInit)
  • ConfigAutoReload : To reload the configuration file and reinit the app(set to true, development only)
  • HandlerCaching : To cache the event handler cfc's in the ColdBox cache. (set to false) You do not want to enable this in development unless you are doing load tests. If not, you won't see changes reflected until you refresh the cache.
  • DefaultLayout : The default layout to use for rendering views.
  • The ses interceptor for pretty URL's.


Step 2: Understanding the Life Cycle

Now that we know how our application will start up and what events to fire we can understand the following life cycle. Please read the Application Life Cycle


Step 3: The Handler Code

The application start, on request start and on request end handlers have no code in them. This is on purpose, so you can fill it up with whatever you want. The only meat for the created application resides on the general handler cfc and on the index method. Our convention is to have a handler called main or implicit and place all implicit events there. Below you can see the full general handler code:

<!-----------------------------------------------------------------------
Author   :      Your Name
Date     :      September 25, 2005
Description :                   
        This is a ColdBox event handler for general methods.

Please note that the extends needs to point to the eventhandler.cfc
in the ColdBox system directory.
extends = coldbox.system.eventhandler
        
----------------------------------------------------------------------->
<cfcomponent name="general" extends="coldbox.system.eventhandler" output="false">
        
        <!--- Event Caching Suffix: It will be appended to every event cached key. This can be a locale, dynamic, etc. --->
        <cfset this.EVENT_CACHE_SUFFIX = "">
        <!--- Pre Handler Execute only if action in this list --->
        <cfset this.PREHANDLER_ONLY = "">
        <!--- Pre Handler Do not execute if action in this except list --->
        <cfset this.PREHANDLER_EXCEPT = "">
        <!--- Post Handler Execute only if action in this list --->
        <cfset this.POSTHANDLER_ONLY = "">
        <!--- Post Handler Do not execute if action in this except list --->
        <cfset this.POSTHANDLER_EXCEPT = "">
        
<!------------------------------------------- CONSTRUCTOR ------------------------------------------>

        <!--- This init is mandatory, including the super.init(). ---> 
        <cffunction name="init" access="public" returntype="general" output="false">
                <cfargument name="controller" type="any">
                <cfset super.init(arguments.controller)>
                <!--- Any constructor code here --->
                <cfreturn this>
        </cffunction>

<!----------------------------------------- IMPLICIT EVENTS ------------------------------------------>

        <!--- UNCOMMENT HANDLER IMPLICIT EVENTS
        
        <!--- preHandler --->
        <cffunction name="preHandler" access="public" returntype="void" output="false" hint="Executes before any event in this handler">
                <cfargument name="Event" type="any" required="yes">
                <cfset var rc = event.getCollection()>
                <cfscript>      
        
                </cfscript>
        </cffunction>
        
        <!--- postHandler --->
        <cffunction name="postHandler" access="public" returntype="void" output="false" hint="Executes after any event in this handler">
                <cfargument name="Event" type="any" required="yes">
                <cfset var rc = event.getCollection()>
                <cfscript>      
        
                </cfscript>
        </cffunction>
        
        <!--- onMissingAction --->
        <cffunction name="onMissingAction" access="public" returntype="void" output="false" hint="Executes if a request action (method) is not found in this handler">
                <cfargument name="Event"                        type="any" required="yes">
                <cfargument name="MissingAction"        type="any" required="true" hint="The requested action string"/>
                <cfset var rc = event.getCollection()>
                <cfscript>      
        
                </cfscript>
        </cffunction>
        
        --->

<!------------------------------------------- PUBLIC EVENTS ------------------------------------------>

        <!--- Default Action --->
        <cffunction name="index" access="public" returntype="void" output="false">
                <cfargument name="Event" type="any">
                <!--- RC Reference --->
                <cfset var rc = event.getCollection()>
                
                <!--- Do Your Logic Here to prepare a view --->
                <cfset Event.setValue("welcomeMessage","Welcome to ColdBox!")>  
                
                <!--- Set the View To Display, after Logic --->
                <cfset Event.setView("home")>
        </cffunction>
        
        <!--- Do Something Action --->
        <cffunction name="doSomething" access="public" returntype="void" output="false">
                <cfargument name="Event" type="any">
                <!--- RC Reference --->
                <cfset var rc = event.getCollection()>
                
                <!--- Do Your Logic Here, call to models, etc.--->

                <!--- Set the next event to run, after Logic, this relocates the browser--->
                <cfset setNextEvent("general.index")>
        </cffunction>

<!------------------------------------------- PRIVATE EVENTS ------------------------------------------>

        
</cfcomponent>

You can see that we have divided it into several sections:

  • Dependencies : Where cfproperty dependencies go. (See [wiki:cbAutowireGuide Autowire Guide)
  • Implicit Events : Some local interception points and local handler implicit executions
  • Public Events : Methods (actions) that are registered as public/remote access are considered public ColdBox Responding events.
  • Private Events : Methods (actions) that can only be called from within the framework

Before I go into the code for this sample, you might be asking yourself why two cfc's for this. Well, remember that controllers are objects also. Don't try to have only one controller doing everything for you, that is plain old BAAAD!! You need to analyze your application and figure out logical ontologies for your handlers. What is Ontology?

Ontology is the study of being or existence. How this controller exists and why. What events and actions will be described by this handler.

These are all principles that you will need to understand before hand, in order to layout a good event model for your application. In this case, the model is simple. We have two distinct handlers, one for taking care of our implicit events such as onRequestStart and onRequestEnd, and a General handler that will say hello to you. As your applications become more complex and they need more functionality, you will come to start using handler packages. This means, that you will group your handlers into directories. A great example is if you are building a website with a forum and a blog application. You can then package your handlers into a blog directory, a forum directory and a site directory. The possibilities are endless. You can continue to add functionality to your applications without the need of configurations or xml for them.

Back to our example. Below is the simple index method. To figure out the anatomy of an event (method), please look at the Event Handlers Guide.

<cffunction name="index" access="public" returntype="void" output="false">
  <cfargument name="Event" type="coldbox.system.beans.requestContext">
  <!--- Do Your Logic Here to prepare a view --->
  <cfset Event.setValue("welcomeMessage","Welcome to ColdBox!")>        
  <!--- Set the View To Display, after Logic --->
  <cfset Event.setView("vwHello")>
</cffunction>

First of all, you need to understand that the framework will create an event object for you that handles (simulates) and entire server request. Inside of this object you have a request collection which is a data structure that you use to set/get values for use in your application. All the FORM and URL variables get appended to this collection at the beginning of a request. It also contains more variables that you and the framework set for execution. This is a very handy object that gets passed around from the beginning of a request to the end of a request. Now that you understand that this event object simulates your incoming variables and more we can continue to analyze the code.

See Live API, Request Context Guide

What this method does is first set a value into the event object (request collection) named welcomeMessage with a message. This basically sets a key into the request collection structure with the value you set. Then we proceed to tell the event object to set a view to render called vwHello by using the setView method. This creates a special variable key in the request collection that the framework will pick up later during the request process and render the set view. Below is what the method actually takes in as parameters.

setView(string name, [boolean nolayout], [boolean cache], [string cacheTimeout], [string cacheLastAccessTimeout])

name The name of the view to render
noLayout Boolean flag that tells the framework to render the view with no layout
cache Boolean flag that tells the framework to also cache this view after rendering
cacheTimeout In minutes, tells the framework to cache the view.
cacheLastAccessTimeout In minutes, tells the framework if view not used in X amount, then purge

Ok, man, this stuff is really vague. I tell an object what view to render, then I don't specify a location or even an extension? What is this? Is this magic? Well, the reality is that IT IS MAGIC!! Remember that ColdBox has conventions that make it easy for the framework to find what it needs. That is why you have a handlers directory where you place your event handlers, a config directory where you place your coldbox.xml file or any other configuration files, layouts directory to keep layouts and a views directory where you will place your views. That is why you set the vwHello view, the framework will find it in the views directory as vwHello.cfm. Please read the Directory Layout & Conventions Guide.

Note: When setting views, do not append the .cfm extension. The framework does it for you.

So in summary, this handler does the following:

  • Sets a variable in the request collection via the event object
  • Sets in the request collection the view to render.

Once this method gets executed by the framework, the internal sequence of the framework will then continue to render the specified template.


Step 4: Layout/View combination

Now, how in the world, does my view get rendered. Well, ColdBox provides you with a very simple but flexible and powerful layout manager and renderer. The basic principles of rendering views in ColdBox is that in your coldbox.xml you declare a DefaultLayout variable that points to the actual name of the template to use as your layout or container for views to be rendered in. Look below at the sample snippet from the configuration file:

<!--Declare Layouts for your application here-->
<Layouts>
        <!--Declare the default layout, MANDATORY-->
        <DefaultLayout>Layout.Main.cfm</DefaultLayout>
        
        <!--Declare other layouts, with view assignments if needed, else do not write them-->
        <Layout file="Layout.Popup.cfm" name="popup">
                <!--You can declare all the views that you want to appear with the above layout-->
                <View>vwTest</View>
                <View>vwMyView</View>
        </Layout>
</Layouts>

As you can see from the snippet above, the default layout is called Layout.Main.cfm. This is a mandatory setting for your application configuration. The other xml elements below is where you can declare implicit renderings of views. In human terms, this is to implicitly determine in which layout to render the specified view(s) without actually telling the framework at runtime. In this sample a Popup layout is declared and two views with it: vwTest and vwMyView. This means, that those two views will be rendered inside of the Popup layout unless you specifically override them via the API.

Note: ColdBox 2.5.0 and greater allows you to have folder layout inheritance. You can declare a Folder element.

The layout source code is shown below:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Welcome to Coldbox!!</title>
<style>
        body {
            font: 10pt verdana;
            font-family: verdana;
            padding: 0;
            margin: 0;
        }
        a {
                color: #0087dd;
                background-color: inherit;
                text-decoration: none;
        }
        a:hover {
                color: #CC0001; 
                background-color: inherit;
                border-bottom:1px dotted #009CFF;
        }
        a.selected{
                color: #CC0001; 
                background-color: inherit;
                border-bottom:1px dotted #009CFF;       
        }
        pre {
             font-size: 80%;
             padding: 10px;
             border: 1px solid #EEEEEE;
         }
        #infobox{
                border:1px solid #CCCCCC;
                padding:10px;
                background-color:#fffff0;
                margin:10px 25px 10px 25px;
         }  
         td {
             font: 10pt verdana;
             font-family: verdana;
             height: 100%;
             padding: 10px;
             margin: 0;
         }
         h2 {
             width: 100%;
             background-color: black;
                 margin: 0px;
             color: #FFFFFF;
             padding: 20px;
         }
         #sidebar {
             border-left: 1px solid #DDDDDD;
             width:250px;
         }
         
         #sidebar ul {
             margin-left: 0;
             padding-left: 0;
         }
         
         #sidebar ul h3 {
             margin-top: 25px;
             font-size: 16px;
             padding-bottom: 10px;
             border-bottom: 1px solid #ccc;
         }
         
         #sidebar li {
             list-style-type: none;
         }
         
         #sidebar ul.links li {
             margin-bottom: 5px;
         }
</style>
</head>
<body>
<!--- Render The View. This is set wherever you want to render the view in your Layout. --->
<cfoutput>#renderView()#</cfoutput>
</body>
</html>

This is a very simple layout. You declare a simple html template and in between the body tags is where I will render my views. This is of course very simplistic. Once you get into AJAX interaction you can render views with no layouts, remove debugging, etc. For this simple example, just note that the method renderView() gets executed. One good thing to know here is that all layouts and views get rendered in their own context inside of the renderer plugin (see Live API ) This is why you can call the method directly and not use the full call getPlugin("renderer").renderView() which you can still use.

Now to the view. Below is the source:

<cfoutput>
<h2><img src="includes/images/coldbox.png" align="absmiddle" style="padding-right:10px"> #Event.getValue("welcomeMessage")#</h2>

<div id="infobox">
<p>
    You are now running <strong>#getSetting("codename",1)# #getSetting("version",1)# (#getsetting("suffix",1)#)</strong>.
        Welcome to the next generation of ColdFusion applications.  You can now start building your application with ease, we already did the hard work
        for you.
</p>
</div>

<table cellpadding="10" width="98%" align="center">
    <tr>
        <td valign="top">
            <h3>Getting Started</h3>
            <p>
                You have just auto-generated your application and are ready to customize your application.  Several directories and
                                files have been created for you.  Please familiarize yourself with your application layout before customizing your
                                application.
                  </p>
          <h4>Good Starting Links</h4>
            <p>
                <ol>
                    <li>
                        <a href="http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbDirectoryStructure">Directory Structure & Conventions</a>
                    </li>
                    <li>
                        <a href="http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbConfigGuide">Coldbox.xml Guide</a>
</pre>
                    </li>
                    <li>
                        <a href="http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbEventHandlersGuide">Event Handler's Guide</a>
                    </li>
                                        <li>
                        <a href="http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbRequestContext">Request Context's Guide</a>
                    </li>
                                        <li>
                        <a href="http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbLayoutsViewsGuide">Layouts & Views Guide</a>
                    </li>
                                        <li>
                                                <a href="http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbMyFirstApp">My First ColdBox App</a>
                                        </li>
            </ol>
                        <sub>* <a href="http://ortus.svnrepository.com/coldbox/trac.cgi">Wiki Docs</a></sub>
            </p>
                        <h4>ColdBox URL Actions</h4>
                        <p>ColdBox can use some very important URL actions to interact with your application. You can try them out below:</p>
                        <p>
                                <ol>
                    <li>
                                                <a href="index.cfm?fwreinit=true">Reinitialize the framework</a> (fwreinit=1)
                                        </li>
                                        <li>
                                                <a href="index.cfm?debugmode=false">Remove Debug Mode</a> (debugmode=false)
                                        </li>
                                        <li>
                                                <a href="index.cfm?debugmode=true">Enable Debug Mode</a> (debugmode=true)
                                        </li>
                                </ol>
                                <sub>* <a href="http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbURLActions">URL Actions Guide</a></sub>
                        </p>
            <h4>Customizing your Application</h4>
            <p>
                You can now start editing your application and building great ColdBox enabled apps. Important files & locations:
                <ol>
                    <li>
                        <b>/config/coldbox.xml.cfm</b>: Your application configuration file
                    </li>
                    <li>
                        <b>/config/environments.xml.cfm</b>: Your per-tier settings
                    </li>
                                         <li>
                        <b>/config/routes.cfm</b>: Your SES routing table
                    </li>
                    <li>
                        <b>/handlers</b>: Your Application controllers
                    </li>
                                        <li>
                        <b>/includes</b>: Assets, Helpers, i18n, templates and more.
                    </li>
                                        <li>
                        <b>/includes/helpers</b>: Place all your application and specific helpers here
                    </li>
                                        <li>
                        <b>/layouts</b>: Where you place all your application layouts
                    </li>
                                        <li>
                        <b>/logs</b>: The ColdBox Logs directory
                    </li>
                                        <li>
                        <b>/model</b>: The meat of your app, your business logic objects
                    </li>
                                        <li>
                        <b>/plugins</b>: Where you place custom plugins built by you!
                    </li>
                                        <li>
                        <b>/test</b>: Your unit testing folder (Just DO IT!!)
                    </li>
                                        <li>
                        <b>/views</b>: Where you create all your views and viewlets
                    </li>
                </ol>
            </p>
        </td>
                
                
                
        <td valign="top" id="sidebar">
        <h3>Docs Search</h3>
                <p>Search all of the docs</p>
        <li>
                        <form id="search" method="get" action="http://ortus.svnrepository.com/coldbox/trac.cgi/search">
                                <div>
                                <input id="proj-search" type="text" value="" accesskey="f" size="15" name="q"/>
                                <input type="submit" value="Search"/>
                                <input type="hidden" value="on" name="wiki"/>
                                <input type="hidden" value="off" name="changeset"/>
                                <input type="hidden" value="on" name="ticket"/>
                                </div>
                        </form>
        </li>
        <li>
            <h3>ColdBox Community Links</h3>
            <ul class="links">
                <li>
                    <a href="http://www.coldboxframework.com">ColdBox Site</a>
                </li>
                <li>
                    <a href="http://blog.coldboxframework.com">Blog</a>
                </li>
                <li>
                    <a href="http://forums.coldboxframework.com/">Forums</a>
                </li>
                <li>
                    <a href="http://ortus.svnrepository.com/coldbox/">Bug Tracker/Wiki</a>
                </li>
                                <li>
                    <a href="http://groups.google.com/group/coldbox">Mailing List</a>
                </li>
                                <li>
                                        <a href="http://www.coldboxframework.com/index.cfm/download/main">Downloads</a>
                                </li>
                                <li>
                                        <a href="http://www.coldboxframework.com/api/">ColdBox API</a>
                                </li>
                                <li>
                                        <a href="http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbCodeDepot">Code Depot</a>
                                </li>
                                <li>
                                        <a href="http://www.coldboxframework.com/index.cfm/download/videos">ColdBox Videos</a>
                                </li>
                                <li>
                                        <a href="http://www.coldboxframework.com/index.cfm/support/overview">Community Support</a>
                                </li>
                                <li>
                                        <a href="http://www.coldboxframework.com/index.cfm/support/training">Training & Courses</a>
                                </li>
            </ul>
        </li>
                
                <p>&nbsp;</p>
                <div style="margin:auto;text-align:center">
                <img src="http://www.coldboxframework.com/includes/images/logos/poweredby.gif">
                </div>
    </td>
    </tr>
</table>
</cfoutput>

It basically just does a cfoutput and outputs some content. The first output is the welcomeMessage we set in the handler. The second message is actually outputting some framework settings. See Settings Guide to learn to interact with the framework settings. That line gets the current codename, version and suffix of your running framework installation. One thing you will notice is that I also output the same welcome message without actually using the event object but the rc scope. Please see the note below.

Note: All layouts and views have access to the rc scope. This scope is a reference to the current request collection structure. This way it is easier to access variables without going to the event object.

Conclusion

Now get your mind out of procedural code, dive into OO Programming. Please make sure to fasten your seat belts, it WILL GET BUMPY!!