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
get() method to $get()setNextEvent() Removed//Conventions
conventions = {
handlersLocation = "controllers",
viewsLocation = "views",
layoutsLocation = "views",
modelsLocation = "model",
modulesLocation = "modules",
eventAction = "index"
};// flash scope configuration
flash = {
// Available scopes are: session,client,cache,mock or your own class path
scope = "session",
// constructor properties for the flash scope implementation
properties = {},
// automatically inflate flash data into the RC scope at the beginning of a request
inflateToRC = true,
// automatically inflate flash data into the PRC scope at the beginning of a request
inflateToPRC = false,
// automatically purge flash data for you
autoPurge = true,
// automatically save flash scopes at end of a request and on relocations.
autoSave = true
};//Register interceptors as an array, we need order
interceptors = [
{
// The CFC instantiation path
class="",
// The alias to register in WireBox, if not defined it uses the name of the CFC
name="",
// A struct of data to configure the interceptor with.
properties={}
}
{ class="mypath.MyInterceptor",
name="MyInterceptor",
properties={useSetterInjection=false}
}
];//Register Layouts
layouts = [
{
// The alias of a layout
name="",
// The layout file
file="",
// A list of view names to render within this layout
views="",
// A list of regex names to match a view
folders=""
}
// Examples
{ name="tester",file="Layout.tester.cfm",views="vwLogin,test",folders="tags,pdf/single" },
{ name="login",file="Login.cfm",folders="^admin/security"}
];//Layout Settings
layoutSettings = {
// The default layout to use if NOT defined in a request
defaultLayout = "Main.cfm",
// The default view to use to render if NOT defined in a request
defaultView = "youForgot.cfm"
};//LogBox DSL
logBox = {
// The configuration file without fileextension to use for operation, instead of using this structure
configFile = "config/LogBox",
// Appenders
appenders = {
appenderName = {
class="class.to.appender",
layout="class.to.layout",
levelMin=0,
levelMax=4,
properties={
name = value,
prop2 = value 2
}
},
// Root Logger
root = {levelMin="FATAL", levelMax="DEBUG", appenders="*"},
// Granualr Categories
categories = {
"coldbox.system" = { levelMin="FATAL", levelMax="INFO", appenders="*"},
"model.security" = { levelMax="DEBUG", appenders="console"}
}
// Implicit categories
debug = ["coldbox.system.interceptors"],
info = ["model.class", "model2.class2"],
warn = ["model.class", "model2.class2"],
error = ["model.class", "model2.class2"],
fatal = ["model.class", "model2.class2"],
off = ["model.class", "model2.class2"]
};modules = {
// Will auto reload the modules in each request. Great for development but can cause some loading/re-loading issues
autoReload = true,
// An array of modules to load ONLY
include = [],
// An array of modules to EXCLUDE for operation
exclude = [ "paidModule1", "paidModule2" ]
};component {
function configure() {
moduleSettings = {
myModule = {
someSetting = "overridden"
}
};
}
}// Custom Settings
settings = {
useSkins = true,
myCoolArray = [1,2,3,4],
skinsPath = "views/skins",
myUtil = createObject("component","#appmapping#.model.util.MyUtility")
};// wirebox integration
wirebox = {
binder = 'config.WireBox',
singletonReload = true
};function group( struct options={}, body );route( pattern="/news", target="public.news.index" );
route( pattern="/news/recent", target="public.news.recent" );
route( pattern="/news/removed", target="public.news.removed" );
route( pattern="/news/add/:title", target="public.news.add" );
route( pattern="/news/delete/:slug", target="public.news.remove" );
route( pattern="/news/v/:slug", target="public.news.view" );group( { pattern="/news", target="public.news." }, function(){
route( "/", "index" )
.route( "/recent", "recent" )
.route( "/removed", "removed" )
.route( "/add/:title", "add" )
.route( "/delete/:slug", "remove" )
.route( "/v/:slug", "view" );
} );addNamespace( pattern="/testing", namespace="test" );
route( "/testing" ).toNamespaceRouting( "test" );
addNamespace( pattern="/news", namespace="blog" );
route( "/news" ).toNamespaceRouting( "blog" );// Via Grouping
route( "/news" ).toNamespaceRouting( "blog" )
.group( { namespace = "blog" }, function(){
route( "/", "blog.index" )
.route( "/:year-numeric?/:month-numeric?/:day-numeric?", "blog.archives" );
} );
// Via Routing DSL
addNamespace( "/news", "blog" );
route( "/" )
.withNameSpace( "blog" )
.to( "blog.index" );
route( "/:year-numeric?/:month-numeric?/:day-numeric?" )
.withNameSpace( "blog" )
.to( "blog.archives" );
// Example PathInfoProvider for detecting a mobile request
function PathInfoProvider( event ){
var rc = event.getCollection();
var prc = event.getCollection(private=true);
local.URI = CGI.PATH_INFO;
if (reFindNoCase('^/m',local.URI) == 0)
{
// Does not look like this could be a mobile request...
return local.URI;
}
// Mobile Request? Let's find out.
// If the URI is "/m" it is easy to determine that this is a
// request for the Mobile Homepage.
if (len(local.URI) == 2)
{
prc.mobile = true;
// Simply return "/" since they want the mobile homepage
return "/";
}
// Only continue with our mobile evaluation if we have a slash after
// our "/m". Without a slash following the /m the route is something
// else like coldbox.org/makes/cool/stuff
if (REFindNoCase('^/m/',local.URI) == 1)
{
// Looks like we are mobile!
prc.mobile = true;
// Remove our "/m/" determination and continue
// processing for languages...
local.URI = REReplaceNoCase(local.URI,'^/m/','/');
}
// The URI starts with an "m" but does not look like
// a mobile request. So, simply return the URI for normal
// route detection...
return local.URI;
}/**
* Relocate user browser requests to other events, URLs, or URIs.
*
* @event The name of the event to run, if not passed, then it will use the default event found in your configuration file
* @URL The full URL you would like to relocate to instead of an event: ex: URL='http://www.google.com'
* @URI The relative URI you would like to relocate to instead of an event: ex: URI='/mypath/awesome/here'
* @queryString The query string to append, if needed. If in SES mode it will be translated to convention name value pairs
* @persist What request collection keys to persist in flash ram
* @persistStruct A structure key-value pairs to persist in flash ram
* @addToken Whether to add the tokens or not. Default is false
* @ssl Whether to relocate in SSL or not
* @baseURL Use this baseURL instead of the index.cfm that is used by default. You can use this for ssl or any full base url you would like to use. Ex: https://mysite.com/index.cfm
* @postProcessExempt Do not fire the postProcess interceptors
* @statusCode The status code to use in the relocation
*/
void function relocate(
event,
URL,
URI,
queryString,
persist,
struct persistStruct,
boolean addToken,
boolean ssl,
baseURL,
boolean postProcessExempt,
numeric statusCode
)component accessors="true"{
property name="name";
property name="email";
function init(){
setName('');
setEmail('');
}
}box install cbvalidation<cfoutput>#externalView(view='/myViewsMapping/tags/footer')#</cfoutput>controller.getRoutingService()
property name="routingService" inject="coldbox:routingService"property name="userService" inject="provider:UserService";
function getData(){
return userService.$get().search();
}getSetting( "version", true ) ==> getColdBoxSetting( "version" )announce( state, data )function state( event, data, rc, prc, buffer ){
}function preProcess( event, data, buffer, rc, prc )
## instead of
function preProcess( event, interceptData, buffer, rc, prc )coldbox.customErrorTemplate = "/coldbox/system/includes/BugReport.cfm";
// to
coldbox.customErrorTemplate = "/coldbox/system/exceptions/BugReport.cfm";
// Or use our new template
coldbox.customErrorTemplate = "/coldbox/system/exceptions/Whoops.cfm";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/hello/**
* 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><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" );
}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.json//cachebox configuration
cachebox = {
// Location of the configuration CFC for CacheBox
configFile = "config/CacheBox.cfc",
// Scope registration for CacheBox
scopeRegistration = {enabled=true,scope=application,key=cacheBox},
// Default Cache Configuration
defaultCache = "views",
// Caches Configuration
caches = {}
};coldbox = {
// The name of the application
appName = "My App",
// The name of the incoming URL/FORM/REMOTE variable that tells the framework what event to execute. Ex: index.cfm?event=users.list
eventName = "event",
// The URI of the ColdBox application on the webserver. Use when ColdBox app exists within subdirectory from project root, otherwise can be omitted
appMapping = ""
};coldbox = {
reinitPassword = "h1cker",
reinitKey = "fwReinit",
handlersIndexAutoReload = true
};// reinit with no password
http://localhost/?fwreinit=1
// reinit with password
http://localhost/?fwreinit=mypasscoldbox = {
reinitKey = "myreinit"
}coldbox={
//Implicit Events
defaultEvent = "Main.index",
requestStartHandler = "Main.onRequestStart",
requestEndHandler = "Main.onRequestEnd",
applicationStartHandler = "Main.onAppInit",
applicationEndHandler = "Main.onAppEnd",
sessionStartHandler = "Main.onSessionStart",
sessionEndHandler = "Main.onSessionEnd",
missingTemplateHandler = "Main.onMissingTemplate"
}coldbox={
//Extension Points
applicationHelper = "includes/helpers/ApplicationHelper.cfm",
viewsHelper = "",
modulesExternalLocation = [],
viewsExternalLocation = "",
layoutsExternalLocation = "",
handlersExternalLocation = "",
requestContextDecorator = "",
controllerDecorator = ""
}coldbox = {
// Error/Exception Handling handler
exceptionHandler = "",
// Invalid HTTP method Handler
invalidHTTPMethodHandler = "",
// The handler to execute on invalid events
invalidEventHandler = "",
// The default error template
customErrorTemplate = "/coldbox/system/includes/BugReport-Public.cfm"
}coldbox.customErrorTemplate = "/coldbox/system/includes/BugReport.cfm";coldbox = {
// Persist handlers
handlerCaching = false,
// Activate event caching
eventCaching = true,
// Activate view caching
viewCaching = true,
// Return RC struct on Flex/Soap Calls
proxyReturnCollection = false,
// Activate implicit views
implicitViews = true,
// Case for implicit views
caseSensitiveImplicitViews = true,
// Auto register all model objects in the `models` folder into WireBox
autoMapModels = true,
// Your very own session tracking identifier
identifierProvider = function(){
return my own session tracking id;
}
}environments = {
// The key is the name of the environment
// The value is a list of regex to match against cgi.http_host
development = "^cf2016.,^lucee.,localhost",
staging = "^stg"
};if ( getSetting('environment') == 'development' ){
doSomeMajik();
}/**
* Executed whenever the development environment is detected
*/
function development(){
// Override coldbox directives
coldbox.handlerCaching = false;
coldbox.eventCaching = false;
coldbox.debugPassword = "";
coldbox.reinitPassword = "";
// Add dev only interceptors
arrayAppend( interceptors, {class="#appMapping#.interceptors.CustomLogger} );
}string public detectEnvironment(){
}
component {
variables.util = new coldbox.system.core.util.Util();
this.datasources[ "my_datasource" ] = {
driver = util.getSystemSetting( "DB_DRIVER" ),
host = util.getSystemSetting( "DB_HOST" ),
port = util.getSystemSetting( "DB_PORT" ),
database = util.getSystemSetting( "DB_DATABASE" ),
username = util.getSystemSetting( "DB_USERNAME" ),
password = util.getSystemSetting( "DB_PASSWORD" )
};
}route( ":handler/:action?").end();// Basic Routing
http://localhost/general -> event=general.index
http://localhost/general/index -> event=general.index
// If 'admin' is a package/folder in the handlers directory
http://localhost/admin/general/index -> event=admin.general.index
// If 'admin' is a module
http://localhost/admin/general/index -> event=admin:general.indexhttp://localhost/general/show/page/2/name/luis
# translate to
event=general.show, rc.page=2, rc.name=luis
http://localhost/users/show/export/pdf/name
# translate to
event=users.show, rc.export=pdf, rc.name={empty value}route( "blog/:year/:month?/:day?", "blog.index" );http://localhost/blog/2012/12/22 -> rc.year=2012, rc.month=12, rc.day=22
http://localhost/blog/2012/12-> rc.year=2012, rc.month=12
http://localhost/blog/2012-> rc.year=2012route( "/blog/:year-numeric/:month-numeric/:day-numeric" );
route( "/blog/:year-numeric/:month-numeric" );
route( "/blog/:year-numeric/" );
route( "/blog/" );route( "/blog/:year-numeric?/:month-numeric?/:day-numeric?" );route( "blog/:year-numeric/:month-numeric?/:day-numeric?", "blog.index" );route( "wiki/:page-alpha", "wiki.show" );// route with regex placeholders
route(
pattern="/api/:format-regex:(xml|json)/",
target="api.execute"
);// route with custom constraints
route(
pattern = "/api/:format/:entryID",
target = "api.execute"
).constraints( {
format = "(xml|json)",
entryID = "([0-9]{4})"
} );route( "/wiki:pagename", "wiki.page" );
route(
pattern="/users/:id/profile",
target="users:profile.show",
name="userprofile"
);route(
pattern="/echo",
target=function( event, rc, prc ){
return "hello ColdBox!";
}
);
route(
pattern="/users",
target=function( event, rc, prc ){
return getInstance( "UserService" ).list();
}
);route(
"/echo/:name",
"<h1>Hello {name} how are you today!</h1>"
);route( "/wiki/:pagename" )
.to( "wiki.show" );
route( "/users/:id/profile" )
.as( "userProfile" )
.to( "users:profile.show" );
route( "/users/:id/profile" )
.as( "userProfile" )
.withVerbs( "GET" )
.withSSL()
.header( "cache", false )
.prc( "isActive", true )
.to( "users:profile.show" );route( "wiki/:pagename" )
.as( "wikipage" )
.withAction( "show" )
.toHandler( "wiki" );
route( "wiki/:pagename" )
.withHander( "wiki" )
.withAction( "show" )
.end();route( "/contact-us" )
.toView(
view = "view name",
layout = "layout",
nolayout = false,
viewModule = "moduleName",
layoutModule = "moduleName"
);route( "/my-old/link" )
.toRedirect( target="/new/pattern", statusCode=301 );route( "/my-old/link" )
.toRedirect( ( route, params, event ) => "/new/route" )
route( "/my-old/link" )
.toRedirect( function( route, params, event ){
return "/new/route";
} ) route( "/old/api/users/:id" )
.toRedirect( ( route, params, event ) => {
return "/api/v1/users/#params.id#" }
)// Action comes via the URL
route( "/users/:action" )
.toHandler( "users" );// RESTFul actions
route( "/users/:id?" )
.withAction( {
GET : "index",
POST : "save",
PUT : "update",
DELETE : "remove"
} )
.toHandler( "users" );/**
* Setup a response for a URL pattern
* @body A closure/lambda or enhanced HTML string
* @statusCode The status code to send
* @statusText The status code to send
*/
function toResponse(
required body,
numeric statusCode = 200,
statusText = "Ok"
)// Simple response routing
route( "/users/hello", function( event, rc, prc ){
return "<h1>Hello From RESTLand</h1>";
} );
// Simple response routing with placeholders
route( "/users/:username", function( event, rc, prc ){
return "<h1>Hello #encodeForHTML( rc.username )# From RESTLand</h1>";
} );
// Routing with the toResponse() method
route( "/users/:id" )
.toResponse( function( event, rc, prc ){
var oUser = getInstance( "UserService" ).get( rc.id ?: 0 );
if( oUser.isLoaded() ){
return oUser.getMemento();
}
event.setHTTPHeader( statusCode = 400, statusText = "Invalid User ID provided" );
return {
"error" : true,
"messages" : "Invalid User ID Provided"
};
} );// Routing with enhanced HTML strings
route( "/users/:id" )
.toResponse(
"<h1>Welcome back user: {id} how are you today!</h1>"
);route( "/" )
.withDomain( "subdomain-routing.dev" )
.to( "subdomain.index" );
route( "/" )
.withDomain( ":username.forgebox.dev" )
.to( "subdomain.show" );route( "/api/v1/users/:id" )
.rcAppend( { secured : true } )
.prcAppend( { name : "hello" } )
.to( "api-v1:users.show" );route( "/go/firefox" )
withCondition( function( requestString ){
return ( findnocase( "Firefox", cgi.HTTP_USER_AGENT ) ? true : false );
});
.to( "firefox.index" );// Using the pattern by convention
route( pattern="/healthcheck" ).to( "healthcheck" );
// Using the name argument
route(
pattern = "/users/list",
target = "users.index",
name = "usermanager"
);
route(
pattern = "/user/:id/profile",
target = "users.show",
name = "userprofile"
);
// Using the as() method
route( "/users/:id/profile" )
.as( "usersprofile" )
.to( "users.show" )route(
// The name of the route
required name,
// The params to pass, can be a struct or array
struct params={},
// Force or un-force SSL, by default we keep the same protocol of the request
boolean ssl
);route(
pattern = "/users/list",
target = "users.index",
name = "usermanager"
);
route(
pattern = "/user/:id/profile",
target = "users.show",
name = "userprofile"
);<!-- Named Route with no params -->
<a href="#event.route( 'usermanager' )#">Manage Users</a>
<!-- Named Route with struct params -->
<a href="#event.route( 'userprofile', { id = 3 } )#">View User</a>
<!-- Named Route with array params -->
<a href="#event.route( 'userprofile', [ 3 ] )#">View User</a>
<a href="#event.route( '/healthcheck' )#">Health check</a>/**
* 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 = ""
){<a href="#event.buildLink( 'home.about' )#">About</a>
<a href="#event.buildLink( 'user.edit.id.#user.getID()#' )#">Edit User</a><a href="#event.buildLink( 'home.about', "page=2&format=simple" )#">About</a>
<a href="#event.buildLink( 'home.about', { page : 2, format: "simple" } )#">About</a>
event.buildLink( {
name : "routeName",
params : { ... }
} )
event.route( "routeName", { ... } )http://localhost/users
http://localhost/users.json
http://localhost/users.xml
http://localhost/users.pdf
http://localhost/users.html http://localhost/users => rc.format is null, does not exist
http://localhost/users.json => rc.format = json
http://localhost/users.xml => rc.format = xml
http://localhost/users.pdf => rc.format = pdf
http://localhost/users.html => rc.format = htmlevent.setView( 'view' );event.setView( 'mydirectory/myView' );function index( event, rc, prc ){
// Inline
event.setView( view="main/index", layout="2columns" );
// Concatenated
event.setView( "main/index" )
.setLayout( "2columns" );
}function index( event, rc, prc ){
// Inline
event.setView( view="widgets/users", nolayout=true );
}* @view The name of the view to set. If a layout has been defined it will assign it, else if will assign the default layout. No extension please
* @args An optional set of arguments that will be available when the view is rendered
* @layout You can override the rendering layout of this setView() call if you want to. Else it defaults to implicit resolution or another override.
* @module The explicit module view
* @noLayout Boolean flag, wether the view sent in will be using a layout or not. Default is false. Uses a pre set layout or the default layout.
* @cache True if you want to cache the rendered view.
* @cacheTimeout The cache timeout in minutes
* @cacheLastAccessTimeout The last access timeout in minutes
* @cacheSuffix Add a cache suffix to the view cache entry. Great for multi-domain caching or i18n caching.
* @cacheProvider The cache provider you want to use for storing the rendered view. By default we use the 'template' cache provider
* @name This triggers a rendering region. This will be the unique name in the request for specifying a rendering region, you can then render it by passing the unique name to renderView();// Cache in the template cache for the default amount of time
event.setView( view='myView', cache=true );
// Cache in the template cache for up to 60 minutes, or 20 minutes after the last time it's been used
event.setView( view='myView', cache=true, cacheTimeout=60, cacheLastAccessTimeout=20 );
// Cache a different version of the view for each language the site has
event.setView( view='myView', cache=true, cacheSuffix=prc.language );var viewData = {
data1 = service.getData1(),
data2 = service.getData2()
};
event.setView( view='myView', args=viewData );<cfoutput>
Data 1: #args.data1#<br>
Data 2: #args.data2#
</cfoutput>event.noRender();relocate( "home" );
relocate( event="shop", ssl=true );
relocate( event="user.view", queryString="id=#rc.id#" );
relocate( url="http://www.google.com" );
relocate( uri="/docs/index.html" )function showData( event, rc, prc ){
prc.data = service.getUsers();
return prc.data;
}function usersAsXML( event, rc, prc ) renderdata='xml'{
prc.data = service.getUsers();
return prc.data;
}
function usersAsPDF( event, rc, prc ) renderdata='pdf'{
prc.data = service.getUsers();
return prc.data;
}component renderdata="xml"{
}function showUser( event, rc, prc ){
return service.getUser( 2 );
}function index(event,rc,prc){
return "<h1>Hello from my handler today at :#now()#</h1>";
}
function myData( event, rc, prc ){
prc.mydata = myservice.getData();
return renderView( "main/myData" );
}/**
* Use this method to tell the framework to render data for you. The framework will take care of marshalling the data for you
* @type The type of data to render. Valid types are JSON, JSONP, JSONT, XML, WDDX, PLAIN/HTML, TEXT, PDF. The deafult is HTML or PLAIN. If an invalid type is sent in, this method will throw an error
* @data The data you would like to marshall and return by the framework
* @contentType The content type of the data. This will be used in the cfcontent tag: text/html, text/plain, text/xml, text/json, etc. The default value is text/html. However, if you choose JSON this method will choose application/json, if you choose WDDX or XML this method will choose text/xml for you.
* @encoding The default character encoding to use. The default encoding is utf-8
* @statusCode The HTTP status code to send to the browser. Defaults to 200
* @statusText Explains the HTTP status code sent to the browser.
* @location Optional argument used to set the HTTP Location header
* @jsonCallback Only needed when using JSONP, this is the callback to add to the JSON packet
* @jsonQueryFormat JSON Only: This parameter can be a Boolean value that specifies how to serialize ColdFusion queries or a string with possible values "row", "column", or "struct".
* @jsonAsText If set to false, defaults content mime-type to application/json, else will change encoding to plain/text
* @xmlColumnList XML Only: Choose which columns to inspect, by default it uses all the columns in the query, if using a query
* @xmlUseCDATA XML Only: Use CDATA content for ALL values. The default is false
* @xmlListDelimiter XML Only: The delimiter in the list. Comma by default
* @xmlRootName XML Only: The name of the initial root element of the XML packet
* @pdfArgs All the PDF arguments to pass along to the CFDocument tag.
* @formats The formats list or array that ColdBox should respond to using the passed in data argument. You can pass any of the valid types (JSON,JSONP,JSONT,XML,WDDX,PLAIN,HTML,TEXT,PDF). For PDF and HTML we will try to render the view by convention based on the incoming event
* @formatsView The view that should be used for rendering HTML/PLAIN/PDF. By default ColdBox uses the name of the event as an implicit view
* @formatsRedirect The arguments that should be passed to relocate as part of a redirect for the HTML action. If the format is HTML and this struct is not empty, ColdBox will call relocate with these arguments.
* @isBinary Bit that determines if the data being set for rendering is binary or not.
*/
function renderData(
type="HTML",
required data,
contentType="",
encoding="utf-8",
numeric statusCode=200,
statusText="",
location="",
jsonCallback="",
jsonQueryFormat="true",
boolean jsonAsText=false,
xmlColumnList="",
boolean xmlUseCDATA=false,
xmlListDelimiter=",",
xmlRootName="",
struct pdfArgs={},
formats="",
formatsView="",
formatsRedirect={},
boolean isBinary=false
){// html marshalling
function renderHTML(event,rc,prc){
event.renderData( data="<h1>My HTML</h1>" );
}
// xml marshalling
function getUsersXML(event,rc,prc){
var qUsers = getUserService().getUsers();
event.renderData( type="XML", data=qUsers );
}
//json marshalling
function getUsersJSON(event,rc,prc){
var qUsers = getUserService().getUsers();
event.renderData( type="json", data=qUsers, statusCode=403 );
}// from binary
function pdf(event,rc,prc){
var binary = fileReadAsBinary( file.path );
event.renderData( data=binary, type="PDF" );
}
// from content
function pdf(event,rc,prc){
event.renderData( data=renderView("views/page"), type="PDF" );
}// from content and with pdfArgs
function pdf(event,rc,prc){
var pdfArgs = { bookmark = "yes", backgroundVisible = "yes", orientation="landscape" };
event.renderData(data=renderView("views/page"), type="PDF", pdfArgs=pdfArgs);
}event.paramValue("format", "html");
switch( rc.format ){
case "json" : case "jsonp" : case "xml" : {
event.renderData(data=mydata, type=rc.format);
break;
}
case "pdf" : {
event.renderData(data=renderView("even/action"), type="pdf");
break;
}
case "html" : {
event.setView( "event/action" );
break;
}
};event.renderData( data=MyData, formats="xml,json,html,pdf" );event.renderData( data=MyData, formats="xml,json,html,pdf", formatsView="data/MyView" );event.renderData( data=MyData, formats="xml,json,html,pdf", formatsRedirect={event="Main.index"} );// get an instance of your custom converter
myConverter = getInstance("MyConverter")
// put some data in it
myConverter.setData( data );
// marshall it out according to your conversions and the content type it supports
event.renderData( data= myConverter, contentType=myConverter.getContentType() );component accessors="true"{
property name="data" type="mytype";
property name="contentType";
function init(){
setContentType("text");
return this;
}
// The magical rendering
function $renderdata(){
var d = {
n = data.getName(),
a = data.getAge(),
c = data.getCoo(),
today = now()
};
return d.toString();
}
}/**
* This method will send a file to the browser or requested HTTP protocol according to arguments.
* CF11+ Compatibility
*
* @file The absolute path to the file or a binary file to send
* @name The name to send to the browser via content disposition header. If not provided then the name of the file or a UUID for a binary file will be used
* @mimeType A valid mime type to use. If not passed, then we will try to use one according to file type
* @disposition The browser content disposition (attachment/inline) header
* @abortAtEnd If true, then this method will do a hard abort, we do not recommend this, prefer the event.noRender() for a graceful abort.
* @extension Only used for binary files which types are not determined.
* @deleteFile Delete the file after it has been streamed to the user. Only used if file is not binary.
*/
function sendFile(
file="",
name="",
mimeType="",
disposition="attachment",
boolean abortAtEnd="false",
extension="",
boolean deleteFile=false
)/**
* Populate a model object from the request Collection or a passed in memento structure
* @model The name of the model to get and populate or the acutal model object. If you already have an instance of a model, then use the populateBean() method
* @scope Use scope injection instead of setters population. Ex: scope=variables.instance.
* @trustedSetter If set to true, the setter method will be called even if it does not exist in the object
* @include A list of keys to include in the population
* @exclude A list of keys to exclude in the population
* @ignoreEmpty Ignore empty values on populations, great for ORM population
* @nullEmptyInclude A list of keys to NULL when empty
* @nullEmptyExclude A list of keys to NOT NULL when empty
* @composeRelationships Automatically attempt to compose relationships from memento
* @memento A structure to populate the model, if not passed it defaults to the request collection
* @jsonstring If you pass a json string, we will populate your model with it
* @xml If you pass an xml string, we will populate your model with it
* @qry If you pass a query, we will populate your model with it
* @rowNumber The row of the qry parameter to populate your model with
*/
function populateModel(
required model,
scope="",
boolean trustedSetter=false,
include="",
exclude="",
boolean ignoreEmpty=false,
nullEmptyInclude="",
nullEmptyExclude="",
boolean composeRelationships=false,
struct memento=getRequestCollection(),
string jsonstring,
string xml,
query qry
){<cfoutput>
<h1>Funky Person Form</h1>
#html.startForm(action='person.save')#
#html.textfield(label="Your Name:",name="name",wrapper="div")#
#html.textfield(label="Your Email:",name="email",wrapper="div")#
#html.submitButton(value="Save")#
#html.endForm()#
</cfoutput>component{
function editor(event,rc,prc){
event.setView("person/editor");
}
function save(event,rc,prc){
var person = populateModel( "Person" );
writeDump( person );abort;
}
}function delete(event,rc,prc){
// determine incoming http method
if( event.getHTTPMethod() == "GET" ){
flash.put("notice","invalid action");
relocate("users.list");
}
else{
// do delete here.
}
}this.allowedMethods = {
actionName : "List of approved HTTP Verbs"
};component{
this.allowedMethods = {
delete : "POST,DELETE",
list : "GET"
};
function list(event,rc,prc){
// list only
}
function delete(event,rc,prc){
// do delete here.
}
}function index( event, rc, prc) allowedMethods="GET,POST"{
// my code here
}// On Error
function onError( event, rc, prc, faultAction, exception, eventArguments ){
// prepare a data packet
var data = {
error = true,
messages = exception.message & exception.detail,
data = ""
}
// log via the log variable already prepared by ColdBox
log.error("Exception when executing #arguments.faultAction# #data.messages#", exception);
// render out a json packet according to specs status codes and messages
event.renderData(data=data,type="json",statusCode=500,statusMessage="Error ocurred");
}function onInvalidHTTPMethod( faultAction, event, rc, prc ){
return "Go away!";
}/**
* Executes events with full life-cycle methods and returns the event results if any were returned.
* @event The event string to execute, if nothing is passed we will execute the application's default event.
* @prePostExempt If true, pre/post handlers will not be fired. Defaults to false
* @private Execute a private event if set, else defaults to public events
* @defaultEvent The flag that let's this service now if it is the default event running or not. USED BY THE FRAMEWORK ONLY
* @eventArguments A collection of arguments to passthrough to the calling event handler method
* @cache Cached the output of the runnable execution, defaults to false. A unique key will be created according to event string + arguments.
* @cacheTimeout The time in minutes to cache the results
* @cacheLastAccessTimeout The time in minutes the results will be removed from cache if idle or requested
* @cacheSuffix The suffix to add into the cache entry for this event rendering
* @cacheProvider The provider to cache this event rendering in, defaults to 'template'
*/
function runEvent(
event="",
boolean prePostExempt=false,
boolean private=false,
boolean defaultEvent=false,
struct eventArguments={},
boolean cache=false,
cacheTimeout="",
cacheLastAccessTimeout="",
cacheSuffix="",
cacheProvider="template"
)//public event
runEvent( 'users.save' );
//post exempt
runEvent( event='users.save', prePostExempt=true );
//Private event
runEvent( event='users.persist', private=true );
// Run event as a widget
<cfoutput>#runEvent(
event = 'widgets.userInfo',
prePostExempt = true,
eventArguments= { widget=true }
)#</cfoutput>
// Run with Caching
runEvent( event="users.list", cache=true, cacheTimeout=30 );// handler responding to widget call
function userInfo( event, rc, prc, widget=false ){
prc.userInfo = userService.get( rc.id );
// set or widget render
if( arguments.widget ){
return renderView( "widgets/userInfo" );
}
// else set view
event.setView( "widgets/userInfo" );
}runEvent( event="users.widget", eventArguments={ max=10, page=1 }, cache=true );
// Cached as a new key
runEvent( event="users.widget", eventArguments={ max=10, page=2 }, cache=true );
/**
* Executes internal named routes with or without parameters. If the named route is not found or the route has no event to execute then this method will throw an `InvalidArgumentException`.
* If you need a route from a module then append the module address: `@moduleName` or prefix it like in run event calls `moduleName:routeName` in order to find the right route.
* The route params will be passed to events as action arguments much how eventArguments work.
*
* @name The name of the route
* @params The parameters of the route to replace
* @cache Cached the output of the runnable execution, defaults to false. A unique key will be created according to event string + arguments.
* @cacheTimeout The time in minutes to cache the results
* @cacheLastAccessTimeout The time in minutes the results will be removed from cache if idle or requested
* @cacheSuffix The suffix to add into the cache entry for this event rendering
* @cacheProvider The provider to cache this event rendering in, defaults to 'template'
* @prePostExempt If true, pre/post handlers will not be fired. Defaults to false
*
* @throws InvalidArgumentException
*/
any function runRoute(
required name,
struct params={},
boolean cache=false,
cacheTimeout="",
cacheLastAccessTimeout="",
cacheSuffix="",
cacheProvider="template",
boolean prePostExempt=false
)component{
property name="userService" inject;
function data( event, rc, prc, id=0 ){
if( id == 0 )
return {};
return userService.getData( id );
}
}# Using @ destination
runRoute( "userData@user", { id=4 } )
# Using : prefix
runRoute( "user:userData", { id=4 } )<div id="leftbar">
#runEvent( event='viewlets.userinfo', eventArguments={ userID=4 } )#
</div>function userinfo( event, rc, prc, userID=0 ){
// place data in prc and prefix it to avoid collisions
prc.userinfo_qData = userService.getUserInfo( arguments.userID );
// render out content
return renderView( "viewlets/userinfo" );
}<cfoutput>
<div>User Info Panel</div>
<div>Username: #prc.userinfo_qData.username#</div>
<div>Last Login: #prc.userinfo_qData.lastLogin#</div>
</cfoutput>function home(event,rc,prc){
// render some content variables with funky arguments
prc.sideColumn = renderView(view='tags/sideColumn',cache=true,cacheTimeout=10);
// set view
event.setView('general/home');
}<div id="content">
<div id="leftColumn">
<cfoutput>#prc.sideColumn#</cfoutput>
</div>
<div id="mainView">
<cfoutput>#renderView()#</cfoutput>
</div>
</div><div id="content">
<div id="leftColumn">
<cfoutput>#prc.sideColumn ?: ''#</cfoutput>
</div>
<div id="mainView">
<cfoutput>#renderView()#</cfoutput>
</div>
</div>ColdBox is a conventions-based HMVC web development framework for ColdFusion (CFML).
June 21, 2022

function data( event, rc, prc ) cache=true cacheTimeout=5{
event.setHTTPHeader( statusCode = 404 );
}public boolean function onRequestStart( targetPage ){
// Set a high timeout for long running tests
setting requestTimeout="9999";
// New ColdBox Virtual Application Starter
request.coldBoxVirtualApp = new coldbox.system.testing.VirtualApp( appMapping = "/root" );
// If hitting the runner or specs, prep our virtual app
if ( getBaseTemplatePath().replace( expandPath( "/tests" ), "" ).reFindNoCase( "(runner|specs)" ) ) {
request.coldBoxVirtualApp.startup();
}
// ORM Reload for fresh results
if( structKeyExists( url, "fwreinit" ) ){
if( structKeyExists( server, "lucee" ) ){
pagePoolClear();
}
// ormReload();
request.coldBoxVirtualApp.restart();
}
return true;
}
public void function onRequestEnd( required targetPage ) {
request.coldBoxVirtualApp.shutdown();
}task( "restricted-task" )
.call( () => ... )
.everyHour()
.startOn( "2022-01-01", "00:00" )
.endOn( "2022-04-01" )function configure(){
xtask( "Disabled Task" )
.call ( function(){
writeDump( var="Disabled", output="console" );
})
.every( 1, "second" );
task( "Scope Test" )
.call( function(){
writeDump( var="****************************************************************************", output="console" );
writeDump( var="Scope Test (application) -> #getThreadName()# #application.keyList()#", output="console" );
writeDump( var="Scope Test (server) -> #getThreadName()# #server.keyList()#", output="console" );
writeDump( var="Scope Test (cgi) -> #getThreadName()# #cgi.keyList()#", output="console" );
writeDump( var="Scope Test (url) -> #getThreadName()# #url.keyList()#", output="console" );
writeDump( var="Scope Test (form) -> #getThreadName()# #form.keyList()#", output="console" );
writeDump( var="Scope Test (request) -> #getThreadName()# #request.keyList()#", output="console" );
writeDump( var="Scope Test (variables) -> #getThreadName()# #variables.keyList()#", output="console" );
writeDump( var="****************************************************************************", output="console" );
} )
.every( 60, "seconds" )
.onFailure( function( task, exception ){
writeDump( var='====> Scope test failed (#getThreadName()#)!! #exception.message# #exception.stacktrace.left( 500 )#', output="console" );
} );
}// Before
task( "my-task" )
.call( () => {} )
.every( 1, 'hours' );
// Which sounds weird when you read it. So now you can use singular
task( "my-task" )
.call( () => {} )
.every( 1, 'hour' );function configure(){
// Set shutdown timeout to 60 seconds
setShutdownTimeout( 60 );
}<div>
<User :data="#forAttribute( prc.user.getMemento() )#">
</div>threadData = announce(
state = "onPageCreate",
data = { page= local.page },
asyncAll = true,
asyncPriority = "high"
);February 02, 2022
apiResources( "users" );
apiResources( "photos" );describe( "subdomain routing", function(){
beforeEach( function(){
setup();
} );
it( "can match on a specific domain", function(){
var event = execute( route: "/", domain: "subdomain-routing.dev" );
var rc = event.getCollection();
expect( rc ).toHaveKey( "event" );
expect( rc.event ).toBe( "subdomain.index" );
} );
it( "skips if the domain is not matched", function(){
var event = execute( route: "/", domain: "not-the-correct-domain.dev" );
var rc = event.getCollection();
expect( rc ).toHaveKey( "event" );
expect( rc.event ).toBe( "main.index" );
} );
it( "can match on a domain with wildcards", function(){
var event = execute( route: "/", domain: "luis.forgebox.dev" );
var rc = event.getCollection();
expect( rc ).toHaveKey( "event" );
expect( rc.event ).toBe( "subdomain.show" );
} );
it( "provides any matched values in the domain in the rc", function(){
var event = execute( route: "/", domain: "luis.forgebox.dev" );
var rc = event.getCollection();
expect( rc ).toHaveKey( "username" );
expect( rc.username ).toBe( "luis" );
} );
} );coldbox : {
identifierProvider : function(){
if( isNull( cookie.mytracker ) ){
cookie.myTracker = createUUID();
}
return cookie.myTracker;
}
}getInstance( name: "CategoryService", injector : "ChildInjector" )// Use the property name as the instance name
property name="categoryService" inject="wirebox:child:childInjector"
// Use a specific instance name
property name="categoryService" inject="wirebox:child:childInjector:CategoryService"
// Use any DSL
property name="categoryService" inject="wirebox:child:childInjector:{DSL}"/**
* Locates, Creates, Injects and Configures an object model instance
*
* @name The mapping name or CFC instance path to try to build up
* @initArguments The constructor structure of arguments to passthrough when initializing the instance
* @dsl The dsl string to use to retrieve the instance model object, mutually exclusive with 'name'
* @targetObject The object requesting the dependency, usually only used by DSL lookups
* @injector The child injector name to use when retrieving the instance
*/
function getInstance(
name,
struct initArguments,
dsl,
targetObject = "",
injector
);July 9th, 2021
component
{
// inject cbauth so we can use it in our interceptor
property name="auth" inject="provider:authenticationService@cbauth";
function preProcess( event ) {
writeDump( auth.isLoggedIn() );
}
}Routines cannot be declared more than once.
The routine auth has been declared twice in different templates.
ColdFusion cannot determine the line of the template that caused this error. This is often caused by an error in the exception handling subsystem.component extends="coldbox.system.testing.BaseTestCase" autowire {
// DI
property name="securityService" inject="provider:securityService";
property name="jwt" inject="provider:JWTService@cbsecurity";
property name="cbsecure" inject="provider:CBSecurity@cbsecurity";
property name="qb" inject="provider:QueryBuilder@qb";
/*********************************** BDD SUITES ***********************************/
function run(){
describe( "Authentication Specs", function(){
beforeEach( function( currentSpec ){
// Setup as a new ColdBox request for this suite, VERY IMPORTANT. ELSE EVERYTHING LOOKS LIKE THE SAME REQUEST.
setup();
// Make sure nothing is logged in to start our calls
securityService.logout();
jwt.getTokenStorage().clearAll();
} );
story( "I want to authenticate a user via username/password and receive a JWT token", function(){
given( "a valid username and password", function(){
then( "I will be authenticated and will receive the JWT token", function(){
// Use a user in the seeded db
var event = this.post(
"/api/v1/login",
{
username : variables.testEmployeeEmail,
password : variables.testPassword
}
);
var response = event.getPrivateValue( "Response" );
expect( response.getError() ).toBeFalse( response.getMessagesString() );
expect( response.getData() ).toHaveKey( "token,user" );
// debug( response.getData() );
var decoded = jwt.decode( response.getData().token );
expect( decoded.sub ).toBe( variables.testEmployeeId );
expect( decoded.exp ).toBeGTE( dateAdd( "h", 1, decoded.iat ) );
expect( response.getData().user.userId ).toBe( variables.testEmployeeId );
} );
} );
given( "invalid username and password", function(){
then( "I will receive a 401 invalid credentials exception ", function(){
var event = this.post(
"/api/v1/login",
{ username : "invalid", password : "invalid" }
);
var response = event.getPrivateValue( "Response" );
expect( response.getError() ).toBeTrue();
expect( response.getStatusCode() ).toBe( 401 );
} );
} );
} );
} );
}
}var event = this.post(
"/api/v1/login",
{ username : "invalid", password : "invalid" }
);
var response = event.getPrivateValue( "Response" );
expect( response.getError() ).toBeTrue();
expect( response.getStatusCode() ).toBe( 401 );
var event = this.post(
"api/v1/timelogs",
{ description : "A nice unit test" }
);
expect( event.getResponse() ).toHaveStatus( 400 );
expect( event.getResponse() ).toHaveInvalidData( "project", "is required" )
expect( event.getResponse() ).toHaveInvalidData( "task", "is required" )
expect( event.getResponse() ).toHaveInvalidData( "user", "is required" )// Parallel Executions
async().all(
() => hyper.post( "/somewhere" ),
() => hyper.post( "/somewhereElse" ),
() => hyper.post( "/another" )
).then( (results)=> logResults( results ) );
// Race Conditions, let the fastest dns resolve
var dnsServer = async().any(
() => dns1.resolve(),
() => dns2.resolve()
).get();
// Process an incoming order
async().newFuture( () => orderService.getOrder() )
.then( (order) => enrichOrder( order ) )
.then( (order) => performPayment( order ) )
.thenAsync(
(order) => dispatchOrder( order ),
async().getExecutor( "cpuIntensive" )
)
.then( (order) => sendConfirmation( order ) );
// Combine Futures
var bmi = async().newFuture( () => weightService.getWeight( rc.person ) )
.thenCombine(
async().newFuture( () => heightService.getHeight( rc.person ) ),
( weight, height ) => {
var heightInMeters = arguments.height/100;
return arguments.weight / (heightInMeters * heightInMeters );
}
)
.get();
// Compose Futures with exceptions
async()
.newFuture( () => userService.getOrFail( rc.id ) )
.thenCompose( ( user ) => creditService.getCreditRating( user ) )
.then( (creditRating) => event.getResponse().setData( creditRating ) )
.onException( (ex) => event.getResponse().setError( true ).setMessages( ex.toString() ) );coldbox-tasks Global ExecutorasyncManager.getExecutor( "coldbox-tasks" )function development() {
coldbox.exceptionEditor = "vscode";
// coldbox.customErrorTemplate = "/coldbox/system/exceptions/BugReport.cfm"; // static bug reports
coldbox.customErrorTemplate = "/coldbox/system/exceptions/Whoops.cfm"; // interactive bug report
}function development() {
coldbox.exceptionEditor = "vscode";
}component extends="coldbox.system.RestHandler"{
function index( event, rc, prc ){
event.getResponse()
.setData( "Hello from restful Land" );
}
}
component resthandler{
function index( event, rc, prc ){
event.getResponse()
.setData( "Hello from restful Land" );
}
}// BaseHandler
component extends="coldbox.system.Resthandler"{
// Modify it here
}
// Then make your own handlers extend from it
component extends="BaseHandler"{
}coldbox create interceptor name=MyInterceptor points=preProcessfunction preProcess( event, interceptData, rc, prc ){
prc.response = wirebox.getInstance( "MyResponseObject" );
} interceptors = [
{
class : "interceptors.MyInterceptor",
name : "MyInterceptor",
properties : {}
}
];when()/**
* Functional construct for if statements
*
* @target The boolean evaluator, this can be a boolean value
* @success The closure/lambda to execute if the boolean value is true
* @failure The closure/lambda to execute if the boolean value is false
*
* @return Returns the super type for chaining
*/
function when( required boolean target, required success, failure )function save( event, rc, prc ){
var oUser = populateModel( "User" );
when( hasAccess(), () => oUser.setRole( rc.role ) );
}coldbox.reinitKey = "cbReinit";application.logbox = new LogBox();
application.logbox = new LogBox( "config.MyLogBox" );// New consistent method
announce( state, data );
// Usage
announce( "myCustomEvent", { data = this } );listen() method to register one-off closures/**
* Register a closure listener as an interceptor on a specific point
*
* @target The closure/lambda to register
* @point The interception point to register the listener to
*/
void function listen( required target, required point )// Within a handler/interceptor/layouts/view
listen( function(){
log.info( "executing from closure listener");
}, "preProcess" );
listen( () => log.info( "executing from closure listener"), "preProcess" );
// Within models (Injecting the interceptor service or controller)
controller
.getInterceptorService()
.listen( function(){
log.info( "executing from closure listener");
}, "preProcess" );onColdBoxShutdown()function onColdBoxShutdown(){
myRabbitMQChannel.close();
}buildLink() Ease of Usestring function buildLink(
to,
queryString = "",
boolean translate = true,
boolean ssl,
baseURL = ""
);
<a href="#event.buildLink( 'main.list', 'userid=4' )#">My Link</a>buildLink() Named Route Support// Using the route() method
event.route( "contactUs", { id : 3 } )
// Using the buildLink() method and the to struct arg
event.buildLink( { name : "contactUs", params : { id : 3 } } )route( "/render/:format" )
.meta( { secure : false } )
.to( "actionRendering.index" );
// Resources
resources(
resource: "photos",
meta : { secure : true }
);if( event.getCurrentRouteMeta().secure ){
// secure it.
}( route, params, event ) => "/new/route"
function( route, params, event ){ return "/new/route"; }route( "/old/api/users/:id" )
.toRedirect( ( route, params, event ) => { return "/api/v1/users/#params.id#" } )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 reinit/**
* 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>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>The ColdBox HMVC Platform is the de-facto enterprise-level HMVC framework for CFML developers.
CommandBox> mkdir playground --cdCommandBox> coldbox create app MyPlaygroundCommandBox> lsCommandBox> start --rewritesEnableCommandBox> edit handlers/main.cfc// Default Action
function index(event,rc,prc){
prc.welcomeMessage = "Welcome to ColdBox!";
event.setView( "main/index" );
}CommandBox> edit views/main/index.cfm<h1>#prc.welcomeMessage#</h1>prc.welcomeMessage = "This is my new welcome message";CommandBox> coldbox create handler helloWorld index,add,edit,listCommandBox> install cbmessageboxCommandBox> list
Dependency Hierarchy for myApp (0.0.0)
+-- cbmessagebox (1.0.0)
+-- coldbox (4.0.0)CommandBox> coldbox create model GreeterService sayHello --opencomponent singleton {
function sayHello(){
return 'Hey you, have an awesome day!';
}
}CommandBox> edit handlers/helloWorld.cfccomponent {
property name='greeterService' inject='greeterService';
property name='messageBox' inject='@cbmessagebox';
...
}function index( event, rc, prc ){
messageBox.info( greeterService.sayHello() );
event.setView( "helloWorld/index" );
}#getInstance( 'messagebox@cbmessageBox').renderIt()#
<div class="container">#renderView()#</div>/**
* Get a setting from the system
*
* @name The key of the setting
* @defaultValue If not found in config, default return value
*
* @throws SettingNotFoundException
*
* @return The requested setting
*/
function getSetting( required name, defaultValue )
/**
* Get a ColdBox setting
*
* @name The key to get
* @defaultValue The default value if it doesn't exist
*
* @throws SettingNotFoundException
*
* @return The framework setting value
*/
function getColdBoxSetting( required name, defaultValue )
/**
* Check if the setting exists in the application
*
* @name The key of the setting
*/
boolean function settingExists( required name )
/**
* Set a new setting in the system
*
* @name The key of the setting
* @value The value of the setting
*
* @return FrameworkSuperType
*/
any function setSetting( required name, required value )
/**
* Get a module's settings structure or a specific setting if the setting key is passed
*
* @module The module to retrieve the configuration settings from
* @setting The setting to retrieve if passed
* @defaultValue The default value to return if setting does not exist
*
* @return struct or any
*/
any function getModuleSettings( required module, setting, defaultValue )controller.getSetting()
controller.getColdBoxSetting()
controller.setSetting()
controller.settingExists()
controller.getConfigSettings()
controller.getColdBoxSettings()application.cbController.getSetting()
application.cbController.setSetting()
application.cbController.settingExists()
application.cbController.getConfigSettings()
application.cbController.getColdBoxSettings()component{
property name="mysetting" inject="coldbox:setting:mysetting";
property name="path" inject="coldbox:coldboxSetting:path";
property name="config" inject="coldbox:configSettings";
property name="settings" inject="coldbox:coldboxSettings";
}Resourceful routes are convention based to help you create routing with less boilerplate.
// Creates all resources that point to a photos event handler by convention
resources( "photos" );
// Register multiple fluently
resources( "photos" )
.resources( "users" )
.resources( "contacts" );
// Creates all resources to the event handler of choice instead of convention
resources( resource="photos", handler="MyPhotoHandler" );
// All resources in a module
resources( resource="photos", handler="photos", module="api" );
// Resources in a ModuleConfig.cfc
router.resources( "photos" )
.resources( resource="users", handler="user" )/**
* Create all RESTful routes for a resource. It will provide automagic mappings between HTTP verbs and URLs to event handlers and actions.
*
* By convention the following rules apply
* - The name of the resource maps to the name of the event handler
* - The default paremeter name is called `:id`
* - The available actions are: index, new, create, show, edit, update, delete
*
* Example: `resource = photos` Then we will create the following routes:
* - `/photos` : `GET` -> `photos.index` Display a list of photos
* - `/photos/new` : `GET` -> `photos.new` Returns an HTML form for creating a new photo
* - `/photos` : `POST` -> `photos.create` Create a new photo
* - `/photos/:id` : `GET` -> `photos.show` Display a specific photo
* - `/photos/:id/edit` : `GET` -> `photos.edit` Return an HTML form for editing a photo
* - `/photos/:id` : `PUT/PATCH` -> `photos.update` Update a specific photo
* - `/photos/:id` : `DELETE` -> `photos.delete` Delete a specific photo
*
* @resource The name of a single resource to map
* @handler The handler for the route. Defaults to the resource name.
* @parameterName The name of the id/parameter for the resource. Defaults to `id`.
* @only Limit routes created with only this list or array of actions, e.g. "index,show"
* @except Exclude routes with an except list or array of actions, e.g. "show"
* @module If passed, the module these resources will be attached to.
* @namespace If passed, the namespace these resources will be attached to.
* @pattern If passed, the actual URL pattern to use, else it defaults to `/#arguments.resource#` the name of the resource.
* @meta A struct of metadata to store with ALL the routes created from this resource
*/
function resources(
required resource,
handler,
parameterName = "id",
only = [],
except = [],
string module = "",
string namespace = "",
string pattern = "",
struct meta = {}
){coldbox create resource helpapiResources( "users" );
apiResources( "photos" );coldbox.handlersExternalLocation = "shared.myapp.handlers";// Rescan handlers on each request, turn OFF in production please
coldbox.handlersIndexAutoReload = true;
// Deactivate singleton caching of the handlers, turn ON in production pleaese
coldbox.handlerCaching = false;component extends="coldbox.system.EventHandler"{
/**
* Default Action
*/
function index( event, rc, prc ){
prc.message = "Hello From ColdBox";
event.setView( "main/index");
}
/**
* Action returning complex data, converted to JSON automatically by ColdBox
*/
function data( event, rc, prc ){
var data = getInstance( "MyModel" ).getArray();
return data;
}
}function name( event, rc, prc )component extends="coldbox.system.EventHandler"{
function index( event, rc, prc ){
return "<h1> Hi from handler land!</h1>";
}
function save( event, rc, prc ){
getInstance( "MyService" ).save( rc );
relocate( "users/list" );
}
function myData( event, rc, prc ){
return ['coldbox', 'wirebox', 'cachebox', 'logbox'];
}
}event={module:}{package.}{handler}{.action}// Call the users.cfc index() method
index.cfm?event=users.index
// Call the users.cfc index() method implicitly
index.cfm?event=users
// Call the users.cfc index() method via URL mappings
index.cfm/users/index
// Call the users.cfc index() method implicitly via URL mappings
index.cfm/users//set a value for views to use
event.setValue( "name", "Luis" );
event.setPrivateValue( "name", "Luis" );
// retrieve a value the user sent
event.getValue( "name" );
// retrieve a value the user sent or give me a default value
event.getValue( "isChecked", false );
// retrieve a private value
event.getPrivateValue( "name" );
// retrieve a private value or give me a default value
event.getPrivateValue( "isChecked", false );
// param a value
event.paramValue( "user_id", "" );
// param a private value
event.paramPrivateValue( "user_id", "" );
// remove a value
event.removeValue( "name" );
// remove a private value
event.removePrivateValue( "name" );
//check if value exists
if( event.valueExists( "name" ) ){
}
//check if private value exists
if( event.privateValueExists( "name" ) ){
}
// set a view for rendering
event.setView( 'blog/index' );
// set a layout for rendering
event.setLayout( 'main' );
// set a view and layout
event.setView( view="blog/userinfo", layout="ajax" );// executes before any action
function preHandler( event, rc, prc, action, eventArguments ){
}
// executes before the list() action ONLY
function preList( event, rc, prc, action, eventArguments ){
}
// concrete example
function preHandler( event, rc, prc, action, eventArguments ){
if( !security.isLoggedIn() ){
event.overrideEvent( 'security.login' );
log.info( "Unauthorized accessed detected!", getHTTPRequestData() );
}
}
function preList( event, rc, prc, action, eventArguments ){
log.info("Starting executing the list action");
}// only fire for the actions: save(), delete()
this.prehandler_only = "save,delete";
// DO NOT fire for the actions: login(), doLogin(), logout()
this.prehandler_except = "login,doLogin,logout"// executes after any action
function postHandler( event, rc, prc, action, eventArguments ){
}
// executes after the list() action ONLY
function postList( event, rc, prc, action, eventArguments ){
}
// concrete examples
function postHandler( event, rc, prc, action, eventArguments ){
log.info("Finalized executing #action#");
}// only fire for the actions: save(), delete()
this.posthandler_only = "save,delete";
// DO NOT fire for the actions: login(), doLogin(), logout()
this.posthandler_except = "login,doLogin,logout"users.list => users.aroundHandler() <=> list()// executes around any action
function aroundHandler(event,targetAction,eventArguments,rc,prc){
}
// executes around the list() action ONLY
function aroundList(event,targetAction,eventArguments,rc,prc){
}
// Around handler advice for transactions
function aroundHandler(event,targetAction,eventArguments,rc,prc){
// log the call
log.debug("Starting to execute #targetAction.toString()#" );
// start a transaction
transaction{
// prepare arguments for action call
var args = {
event = arguments.event,
rc = arguments.rc,
prc = arguments.prc
};
structAppend( args, eventArguments );
// execute the action now
var results = arguments.targetAction( argumentCollection=args );
}
// log the call
log.debug( "Ended executing #targetAction.toString()#" );
// return if it exists
if( !isNull( results ) ){ return results; }
}
// Around handler advice for try/catches
function aroundHandler(event,targetAction,eventArguments,rc,prc){
// log the call
if( log.canDebug() ){
log.debug( "Starting to execute #targetAction.toString()#" );
}
// try block
try{
// prepare arguments for action call
var args = {
event = arguments.event,
rc = arguments.rc,
prc = arguments.prc
};
structAppend( args, eventArguments );
// execute the action now
return arguments.targetAction( argumentCollection=args );
}
catch(Any e){
// log it
log.error("Error executing #targetAction.toString()#: #e.message# #e.detail#", e);
// set exception in request collection and set view to render
event.setValue( "exception", e)
.setView( "errors/generic" );
}
}// only fire for the actions: save(), delete()
this.aroundhandler_only = "save,delete";
// DO NOT fire for the actions: login(), doLogin(), logout()
this.aroundhandler_except = "login,doLogin,logout"+ handlers
+ users.cfc
+ models
+ UserService.cfccomponent name="MyHandler"{
// Dependency injection of the model: UserService -> variables.userService
property name="userService" inject="UserService";
function index( event, rc, prc ){
prc.data = userService.list()
event.setView( "users/index" );
}
}component{
function index( event, rc, prc ){
// Request to use the user service, this would be best to inject instead
// of requesting it.
prc.data = getInstance( "UserService" ).list();
event.setView( "users/index" );
}
function save( event, rc, prc ){
// request a user transient object, populate it and save it.
prc.oUser = populateModel( getInstance( "User" ) );
userService.save( prc.oUser );
relocate( "users/index" );
}
} + application
+ models
+ FunkyService.cfccomponent singleton{
function init(){
return this;
}
function add(a,b){
return a+b;
}
function getFunkyData(){
var data = [
{name="Luis", age="33"},
{name="Jim", age="99"},
{name="Alex", age="1"},
{name="Joe", age="23"}
];
return data;
}
}component{
// Injection via property
property name="funkyService" inject="FunkyService";
function index(event,rc,prc){
prc.data = funkyService.getFunkyData();
event.renderData( data=prc.data, type="xml" );
}
}<array>
<item>
<struct>
<name>Luis</name>
<age>33</age>
</struct>
</item>
<item>
<struct>
<name>Jim</name>
<age>99</age>
</struct>
</item>
<item>
<struct>
<name>Alex</name>
<age>1</age>
</struct>
</item>
<item>
<struct>
<name>Joe</name>
<age>23</age>
</struct>
</item>
</array>// Injection using the DSL by default name/id lookup
property name="funkyService" inject="FunkyService";
// Injection using the DSL id namespace
property name="funkyService" inject="id:FunkyService";
// Injection using the DSL model namespace
property name="funkyService" inject="model:FunkyService";component{
function index(event,rc,prc){
prc.data = getInstance( "FunkyService" ).getFunkyData();
event.renderData( data=prc.data, type="xml" );
}
}component{
function index(event,rc,prc){
prc.data = wirebox.getInstance( "FunkyService" ).getFunkyData();
event.renderData( data=prc.data, type="xml" );
}
}1000 Requests made to users.index
- Injection: 1000 handler calls + 1 model creation and wiring call = 1001 calls
- Requesting: 1000 handler calls + 1000 model retrieval + 1 model creation call = 2002 calls coldbox.eventCaching = true;// In Script
function showEntry(event,rc,prc) cache="true" cacheTimeout="30" cacheLastAccessTimeout="15"{
//get Entry
prc.entry = getEntryService().getEntry(event.getValue('entryID',0));
//set view
event.setView('blog/showEntry');
}templateCache = cachebox.getCache( "template" );//Trigger to purge all Events
getCache( "template" ).clearAllEvents();
//Trigger to purge all events synchronously
getCache( "template" ).clearAllEvents(async=false);
//Purge all events from the blog handler
getCache( "template" ).clearEvent('blog');
//Purge all permutations of the blog.dspBlog event
getCache( "template" ).clearEvent('blog.dspBlog');
//Purge the blog.dspBlog event with entry of 12345
getCache( "template" ).clearEvent('blog.dspBlog','id=12345')this.EVENT_CACHE_SUFFIX = function( eventHandlerBean ){
return "a localized string, etc";
};OnRequestCapture - Influence Cache Keyscomponent{
onRequestCapture(event,interceptData){
var rc = event.getCollection();
// Add user's locale to the request collection to influence event caching
rc._user_locale = getFWLocale();
}
}box install cbdebugger
views or in your configured external locationsproperty name="renderer" inject="provider:coldbox:renderer";<h1>#args.type# User</h1>
<form method="post" action="#args.action#">
...
</form>#renderView(view='forms/universal',args={type='new',action='user.create'})#component
{
function index(event,rc,prc){
// call some model for data and put into the request collection
prc.myQuery = getInstance('MyService').getData();
// set the view for rendering
event.setView( "general/index" );
}
}<cfoutput>
<h1>My Cool Data</h1>
#html.table( data=prc.myQuery, class="table table-striped table-hover" )#
</cfoutput>component{
function index(event,rc,prc){
// call some model for data and put into the request collection
prc.myQuery = getInstance('MyService').getData();
// set the view for rendering
event.setView( view="general/index", noLayout=true );
}
function index(event,rc,prc){
// call some model for data and put into the request collection
prc.myQuery = getInstance('MyService').getData();
// set the view for rendering
event.setView( "general/index" ).noLayout();
}
}component name="general"{
function index(event,rc,prc){
// call some model for data and put into the request collection
prc.myQuery = getInstance('MyService').getData();
// set the view for rendering
event.setView( view="general/index", layout="Ajax" );
}
function index(event,rc,prc){
// call some model for data and put into the request collection
prc.myQuery = getInstance('MyService').getData();
// set the view for rendering
event.setView( "general/index" ).setLayout( "Ajax" );
}
}component name="general"{
function index(event,rc,prc){
// call some model for data and put into the request collection
prc.myQuery = getInstance('MyService').getData();
// set the view for rendering
event.setView( view="general/index", module="shared-views" );
}
}component name="general"{
function saveData(event,rc,prc){
// do your work here …..
// set for no render
event.noRender();
}
}component name="general"{
function index(event,rc,prc){
// call some model for data and put into the request collection
prc.myQuery = getInstance('MyService').getData();
}
}coldbox.implicitViews = false;coldbox.caseSensitiveImplicitViews = true;<cfoutput>
// render inline
#renderView( 'tags/metadata' )#
// render from a module
#renderView( view="security/user", module="security" )#
// render and cache
#renderView(
view="tags/longRendering",
cache=true,
cacheTimeout=5,
cacheProvider="couchbase"
)#
// render a view from the handler action
function showData(event,rc,prc){
// data here
return renderView( "general/showData" );
}
// render an email body content in an email template layout
body = renderlayout( layout='email',view='templates/email_generic' );
</cfoutput>function sendEmail(){
// code here.
var body = renderer.renderView( "templates/email" );
}#renderView(view='forms/universal',args={type='edit',action='user.update'})#
newScheduleonDIComplete() is called twice using virtual inheritanceDateFormat Mask to use lowercase "d" to be compatible with ACF2021+ application
+ layouts
+ viewscomponent{
property name="renderer" inject="coldbox:renderer";
function renderSomething(){
return renderer.renderView( view="mail/mymail", args={} );
}
}




<base href="#event.getHTMLBaseURL()#">



































<cfoutput>
<form method="POST" action="#event.buildLink( 'posts/#prc.post.getId()#' )#">
<input type="hidden" name="_method" value="DELETE" />
<button type="submit">Delete</button>
</form>
</cfoutput><cfoutput>
#html.startForm( action = "posts.#prc.post.getId()#", method="DELETE" )#
#html.submitButton( name = "Delete", class = "btn btn-danger" )#
#html.endForm()#
</cfoutput>// reinit with no password
index.cfm?fwreinit=1
// reinit with password
index.cfm?fwreinit=mypass$ coldbox reinitserver start --rewritesEnableThe ColdBox.cfc is the main applications' configuration object.

// Old Style
http://localhost/index.cfm?event=home.about&page=2
http://localhost/index.cfm?city=24&page=3&county=234324324// New Routing Style
http://localhost/home/about/page/2
http://localhost/dade/miami/page/3function configure(){
// Routing with placeholders to an event with placeholders
route( "/blog/:year-numeric{4}/:month?/:day?" )
.to( "blog.list" );
// Redirects
route( "/old/book" )
.toRedirect( "/mybook" );
// Responses
route( "/echo" ).toResponse( (event,rc,prc) => {
return "hello luis";
} );
// Shortcut to above
route( "/echo", (event,rc,prc) => {
return "hello luis";
} );
// Show view
route( "/contact-us" )
.toView( "main/contact" );
// Direct to handler with action from URL
route( "/users/:action" )
.toHandler( "users" );
// Inline pattern + target and name
route( pattern="/wiki/:page", target="wiki.show", name="wikipage" );
}box install route-visualizer// retrieve it
config = getSetting( 'coldboxConfig' );
// inject it
property name="config" inject="coldbox:setting:coldboxConfig";function preProcess( event, interceptData, buffer, rc, prc ){
writeDump( 'I just hijacked your app!' );abort;
}function preRender( event, interceptData, buffer, rc, prc ){
controller.getWirebox().getInstance( 'loggerService' ).doSomething();
}mkdir myapp --cd
install coldboxDir 0 Apr 25,2018 11:04:05 coldbox
File 112 Apr 25,2018 11:04:05 box.json
RewriteEngine on
#if this call related to adminstrators or non rewrite folders, you can add more here.
RewriteCond %{REQUEST_URI} ^/(.*(CFIDE|cfide|CFFormGateway|jrunscripts|railo-context|lucee|mapping-tag|fckeditor)).*$
RewriteRule ^(.*)$ - [NC,L]
#Images, css, javascript and docs, add your own extensions if needed.
RewriteCond %{REQUEST_URI} \.(bmp|gif|jpe?g|png|css|js|txt|xls|ico|swf)$
RewriteRule ^(.*)$ - [NC,L]
#The ColdBox index.cfm/{path_info} rules.
RewriteRule ^$ index.cfm [QSA,NS]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.cfm/%{REQUEST_URI} [QSA,L,NS]

#The ColdBox index.cfm/{path_info} rules.
RewriteEngine On
RewriteRule ^$ /index.cfm?redirect_path=/ [QSA,NS]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.cfm?redirect_path=%{REQUEST_URI} [QSA,L,NS]function PathInfoProvider( event ){
var p = cgi.path_info;
if (len(p)) {
return p;
} else if (url.keyExists("redirect_path")) {
return url.redirect_path;
} else {
return "";
}
}################### LOCATION: ROOT #####################
location / {
# First attempt to serve real files or directory, else it sends it to the @rewrite location for processing
try_files $uri $uri/ @rewrite;
}
################### @REWRITE: COLDBOX SES RULES #####################
# Rewrite for ColdBox (only needed if you want SES urls with this framework)
# If you don't use SES urls you could do something like this
# location ~ \.(cfm|cfml|cfc)(.*)$ {
location @rewrite {
rewrite ^/(.*)? /index.cfm/$request_uri last;
rewrite ^ /index.cfm last;
}
################### CFM/CFC LUCEE HANDLER #####################
# The above locations will just redirect or try to serve cfml files
# We need this to tell NGinx that if we receive the following requests to pass them to Lucee
location ~ \.(cfm|cfml|cfc|jsp)(.*)$ {
# Include our connector
include lucee.conf;
}<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Application Administration" stopProcessing="true">
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAll">
<add input="{SCRIPT_NAME}" pattern="^/(.*(CFIDE|cfide|CFFormGateway|jrunscripts|lucee|railo-context|fckeditor)).*$" ignoreCase="false" />
</conditions>
<action type="None" />
</rule>
<rule name="Flash and Flex Communication" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{SCRIPT_NAME}" pattern="^/(.*(flashservices|flex2gateway|flex-remoting)).*$" ignoreCase="false" />
</conditions>
<action type="Rewrite" url="index.cfm/{PATH_INFO}" appendQueryString="true" />
</rule>
<rule name="Static Files" stopProcessing="true">
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAll">
<add input="{SCRIPT_NAME}" pattern="\.(bmp|gif|jpe?g|png|css|js|txt|pdf|doc|xls)$" ignoreCase="false" />
</conditions>
<action type="None" />
</rule>
<rule name="Insert index.cfm" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.cfm/{PATH_INFO}" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration><?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN" "http://tuckey.org/res/dtds/urlrewrite3.2.dtd">
<urlrewrite>
<rule>
<note>ContentBox Media URLs</note>
<condition type="request-uri" operator="equal">^/__media/.*$</condition>
<from>^/(.*)$</from>
<to type="passthrough">/index.cfm/$1</to>
</rule>
<rule>
<note>Generic Front-Controller URLs</note>
<condition type="request-uri" operator="notequal">/(index.cfm|robots.txt|osd.xml|flex2gateway|cfide|cfformgateway|railo-context|lucee|admin-context|modules/contentbox-dsncreator|modules/contentbox-installer|modules/contentbox|files|images|js|javascripts|css|styles|config).*</condition>
<condition type="request-uri" operator="notequal">\.(bmp|gif|jpe?g|png|css|js|txt|xls|ico|swf|woff|ttf|otf)$</condition>
<condition type="request-filename" operator="notdir"/>
<condition type="request-filename" operator="notfile"/>
<from>^/(.+)$</from>
<to type="passthrough">/index.cfm/$1</to>
</rule>
</urlrewrite>component{
// Application properties
this.name = hash( getCurrentTemplatePath() );
this.sessionManagement = true;
this.sessionTimeout = createTimeSpan(0,0,30,0);
this.setClientCookies = true;
// COLDBOX STATIC PROPERTY, DO NOT CHANGE UNLESS THIS IS NOT THE ROOT OF YOUR COLDBOX APP
COLDBOX_APP_ROOT_PATH = getDirectoryFromPath( getCurrentTemplatePath() );
// The web server mapping to this application. Used for remote purposes or static purposes
COLDBOX_APP_MAPPING = "";
// COLDBOX PROPERTIES
COLDBOX_CONFIG_FILE = "";
// COLDBOX APPLICATION KEY OVERRIDE
COLDBOX_APP_KEY = "";
// By default if an app is reiniting and a request hits it, we will fail fast with a message
COLDBOX_FAIL_FAST = true;
// application start
public boolean function onApplicationStart(){
application.cbBootstrap = new coldbox.system.Bootstrap( COLDBOX_CONFIG_FILE, COLDBOX_APP_ROOT_PATH, COLDBOX_APP_KEY, COLDBOX_APP_MAPPING, COLDBOX_FAIL_FAST );
application.cbBootstrap.loadColdbox();
return true;
}
// request start
public boolean function onRequestStart(String targetPage){
// Process ColdBox Request
application.cbBootstrap.onRequestStart( arguments.targetPage );
return true;
}
public void function onSessionStart(){
application.cbBootStrap.onSessionStart();
}
public void function onSessionEnd( struct sessionScope, struct appScope ){
arguments.appScope.cbBootStrap.onSessionEnd( argumentCollection=arguments );
}
public boolean function onMissingTemplate( template ){
return application.cbBootstrap.onMissingTemplate( argumentCollection=arguments );
}
}component extends="coldbox.system.Bootstrap"{
// Application properties
this.name = hash( getCurrentTemplatePath() );
this.sessionManagement = true;
this.sessionTimeout = createTimeSpan(0,0,30,0);
this.setClientCookies = true;
// COLDBOX STATIC PROPERTY, DO NOT CHANGE UNLESS THIS IS NOT THE ROOT OF YOUR COLDBOX APP
COLDBOX_APP_ROOT_PATH = getDirectoryFromPath( getCurrentTemplatePath() );
// The web server mapping to this application. Used for remote purposes or static purposes
COLDBOX_APP_MAPPING = "";
// COLDBOX PROPERTIES
COLDBOX_CONFIG_FILE = "";
// COLDBOX APPLICATION KEY OVERRIDE
COLDBOX_APP_KEY = "";
// By default if an app is reiniting and a request hits it, we will fail fast with a message
COLDBOX_FAIL_FAST = true;
}application.bootstrapper.setLockTimeout( 10 );// test if this is an MVC request or a remote request
if ( event.isProxyRequest() ){
event.setValue('message', 'We are in proxy mode right now');
}
// param a variable called page
event.paramValue('page',1);
// then just use it
event.setValue('link','index.cfm?page=#rc.page#');
// get a value with a default value
event.setvalue('link','index.cfm?page=#event.getValue('page',1)#');
// Set the view to render
event.setView('homepage');
// Set the view to render with no layout
event.setView('homepage',true);
// set the view to render with caching stuff
event.setview(name='homepage',cache='true',cacheTimeout='30');
// override a layout
event.setLayout('Layout.Ajax');
// check if a value does not exists
if ( !event.valueExists('username') ) {
}
// Tell the framework to stop processing gracefully, no renderings
event.noRender();
// Build a link
<form action="#event.buildLink( 'user.save' )#" method="post">
</form>component {
function configure() {
// Set Full Rewrites
setFullRewrites( true );
/**
* --------------------------------------------------------------------------
* App Routes
* --------------------------------------------------------------------------
*
* Here is where you can register the routes for your web application!
* Go get Funky!
*
*/
// A nice healthcheck route example
route( "/healthcheck", function( event, rc, prc ) {
return "Ok!";
} );
// A nice RESTFul Route example
route( "/api/echo", function( event, rc, prc ) {
return {
"error" : false,
"data" : "Welcome to my awesome API!"
};
} );
route(
pattern : "/api/contacts",
target : "contacts.index",
name : "api.contacts"
);
// Conventions based routing
route( ":handler/:action?" ).end();
}
}
function configure(){
setFullRewrites( true );
setExtensionDetection( true );
setValidExtensions( "json,cfm,pdf" );
setMultiDomainDiscovery( false )
}

