BoxLang ๐ A New JVM Dynamic Language Learn More...
Copyright Since 2005 ColdBox Platform by Luis Majano
and Ortus Solutions, Corp
www.coldbox.org | www.ortussolutions.com
Welcome to the Modern ColdBox application template! ๐ This template provides a secure, production-ready foundation for building enterprise-grade HMVC (Hierarchical Model-View-Controller) web applications using Adobe ColdFusion or BoxLang.
Unlike traditional ColdBox templates where all files live in the web root, this template implements a security-first architecture by separating your application code from publicly accessible files:
/public
- Only public assets (CSS, JS, images, index.cfm) are web-accessible/app
- Application code (handlers, models, views, config) sits
outside the web root๐ก Perfect for: Production applications, enterprise environments, security-conscious projects, and teams following modern web development practices.
Before getting started, ensure you have the following installed on your operating system:
CommandBox - CLI toolchain, package manager, and server runtime
CFML Engine - Adobe ColdFusion 2021+ OR BoxLang 1.0+
Maven - Java dependency manager (Optional)
Verify your installation:
# Check CommandBox is installed
box version
# Check your CFML engine (BoxLang example)
box boxlang version
# Verify project setup
box install
# Create a new ColdBox application using this Modern template
box coldbox create app name=myApp skeleton=modern
# Navigate into your app directory
cd myApp
# Install dependencies
box install
# Start the web server
box server start
Your application will be available at
http://localhost:8080
๐
Code to your liking and enjoy! ๐
This template follows a security-first architecture where application code lives outside the web root:
/app/
)This folder contains the main ColdBox application code via conventions. It is NOT web-accessible for security.
app/
โโโ ๐ง Application.cfc # Security barrier (contains only "abort")
โโโ config/ # Configuration files
โ โโโ ColdBox.cfc # Main framework settings
โ โโโ Router.cfc # URL routing definitions
โ โโโ WireBox.cfc # Dependency injection (optional)
โ โโโ CacheBox.cfc # Caching configuration (optional)
โโโ ๐ฎ handlers/ # Event handlers (controllers)
โโโ ๐ ๏ธ helpers/ # Application helpers (optional)
โโโ ๐ interceptors/ # Event interceptors/listeners
โโโ ๐จ layouts/ # View layouts
โโโ ๐ logs/ # Application logs
โโโ ๐๏ธ models/ # Business logic models
โโโ ๐ฆ modules/ # Application-specific modules (optional)
โโโ ๐๏ธ views/ # View templates
/public/
)This folder contains ONLY publicly accessible files - the CommandBox server points here.
public/
โโโ ๐ฑ Application.cfc # Bootstrap that maps to /app
โโโ ๐ฏ index.cfm # Main entry point
โโโ ๐ผ๏ธ favicon.ico # Site icon
โโโ ๐ค robots.txt # Search engine directives
โโโ ๐ฆ includes/ # Static assets (CSS, JS, images)
/lib/
)Framework and dependency storage managed by CommandBox:
lib/
โโโ coldbox/ # ColdBox framework files
โโโ testbox/ # TestBox testing framework
โโโ java/ # Java JAR dependencies (optional)
โโโ modules/ # CommandBox-installed modules
/tests/
)Test suites for your application:
tests/
โโโ Application.cfc # Test application setup
โโโ runner.cfm # TestBox test runner
โโโ index.cfm # Test entry point
โโโ specs/ # BDD test specifications
โโโ integration/ # Integration tests
โโโ ๐ box.json # CommandBox dependencies and project descriptor
โโโ ๐๏ธ pom.xml # Maven dependencies (optional)
โโโ ๐ฅ๏ธ server.json # CommandBox server configuration (CRITICAL for aliases)
โโโ ๐ณ docker/ # Docker configuration
โโโ ๐ resources/ # Non-web resources
โ โโโ database/ # Database migrations/seeders
โ โโโ apidocs/ # API documentation
โโโ .env.example # Environment variable template
โโโ .cfconfig.json # CFML engine configuration
โโโ .cfformat.json # Code formatting rules
โโโ .editorconfig # Editor configuration
Because application code lives outside /public
, you
must configure CommandBox aliases in
server.json
to expose internal paths for modules with UI assets:
"web": {
"webroot": "public",
"rewrites": {
"enable": true
},
"aliases": {
"/coldbox/system/exceptions": "./lib/coldbox/system/exceptions/",
"/tests": "./tests/"
}
}
When you install ColdBox modules that have web-accessible assets
(like cbdebugger
, cbswagger
,
relax
), you MUST add aliases:
# Install a module with UI
box install cbdebugger
# Add the alias to server.json
"aliases": {
"/cbdebugger": "./modules/cbdebugger",
"/coldbox/system/exceptions": "./lib/coldbox/system/exceptions/",
"/tests": "./tests/"
}
# Restart the server
box server restart
โ ๏ธ Important: Without proper aliases, module UI assets will return 404 errors. This is the most common issue when using the Modern template.
Understanding the bootstrap flow is critical for working with this template:
/public/index.cfm
/public/Application.cfc
sets critical mappings: COLDBOX_APP_ROOT_PATH = this.mappings["/app"]
COLDBOX_APP_MAPPING = "/app"
COLDBOX_WEB_MAPPING = "/"
/app/config/ColdBox.cfc
/app/config/Router.cfc
/app/handlers/
Security Note: /app/Application.cfc
contains only abort;
to prevent direct web access to
application code.
# Install all dependencies
box install
# Install a specific module
box install cbsecurity
# Install development dependencies
box install testbox --saveDev
# Start server (uses server.json config)
box server start
# Start with specific engine
box server start cfengine=boxlang@be
# Stop server
box server stop
# Restart server
box server restart
# Open server in browser
box server open
# Format all code
box run-script format
# Check formatting without changes
box run-script format:check
# Watch mode - auto-format on save
box run-script format:watch
# Run all tests
box testbox run
# Run tests in browser
box server start
# Navigate to: http://localhost:8080/tests
Tests extend coldbox.system.testing.BaseTestCase
with appMapping="/app"
:
component extends="coldbox.system.testing.BaseTestCase" appMapping="/app" {
function beforeAll(){
super.beforeAll();
// Global test setup
}
function run(){
describe("User Handler", function(){
beforeEach(function(currentSpec){
// CRITICAL: Call setup() to create fresh request context
setup();
});
it("can list users", function(){
var event = this.get("users.index");
expect(event.getValue(name="users", private=true))
.toBeArray();
});
it("can show a user", function(){
var event = this.get("users.show?id=1");
expect(event.getValue(name="user", private=true))
.toBeStruct();
});
});
}
}
Key Testing Methods:
this.get(event)
/ this.post(event)
-
Simulate HTTP requestsexecute(event)
- Execute event without HTTP simulationevent.getValue(name, default, private)
- Get from rc/prcevent.getHandlerResults()
- Get return value from handler# Build Docker container
box run-script build:docker
# Run Docker container
box run-script run:docker
We include a docker/docker-compose.yml
stack with
database support:
# Start the stack
cd docker
docker-compose up -d
# Stop the stack
docker-compose down
# View logs
docker-compose logs -f
If your project relies on Java third-party dependencies, use the
included Maven pom.xml
:
<!-- Add to pom.xml -->
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
Then download dependencies:
mvn install
JARs are copied to /lib/java/
and automatically
class-loaded by Application.cfc
via this.javaSettings.loadPaths
.
You can find Java dependencies at: https://central.sonatype.com/
Copy .env.example
to .env
:
cp .env.example .env
Use getSystemSetting()
in your config:
// In /app/config/ColdBox.cfc
variables.coldbox = {
appName: getSystemSetting("APPNAME", "My App")
};
// In your handlers/models
variables.apiKey = getSystemSetting("API_KEY");
Set environment variables:
# In .env file
APPNAME=My Awesome App
API_KEY=your-secret-key
Use WireBox annotations for dependency injection:
component {
property name="userService" inject="UserService";
property name="wirebox" inject="wirebox";
property name="cachebox" inject="cachebox";
property name="logbox" inject="logbox";
function list(){
return userService.getAll();
}
}
Common Injection Patterns:
inject="coldbox"
- ColdBox controllerinject="wirebox"
- WireBox injectorinject="cachebox:default"
- Default cacheinject="logbox:root"
- Root loggerinject="coldbox:setting: settingName"
-
Application settingcomponent extends="coldbox.system.EventHandler" {
// All actions receive three arguments:
function index(event, rc, prc){
// rc = Request collection (FORM/URL variables)
// prc = Private request collection (handler-to-view data)
prc.users = userService.list();
event.setView("users/index");
}
// RESTful responses
function data(event, rc, prc){
return [
{ "id": 1, "name": "Luis" },
{ "id": 2, "name": "Joe" }
];
}
// Relocations
function save(event, rc, prc){
userService.save(rc);
relocate("users.index");
}
}
In /app/config/Router.cfc
:
component {
function configure(){
// Named routes
route("/healthcheck", function(event, rc, prc){
return "Ok!";
});
// RESTful resources
resources("users");
// API routes
route("/api/v1/users", function(event, rc, prc){
return { "data": userService.list() };
});
// Conventions-based routing (keep at end)
route(":handler/:action?").end();
}
}
We include VSCode configuration to enhance your development experience:
.vscode/settings.json
- Introspection helpers for
ColdBox and TestBox ๐.vscode/tasks.json
- Tasks to run CommandBox tasks and
TestBox bundles โกRun CommandBox Task
- Open a CommandBox task and run it ๐โโ๏ธRun TestBox Bundle
- Open the bundle you want to test
and run it ๐งชTo run tasks: Open command palette (โงโB
on Mac) and
choose Tasks: Run Build Task
ColdBox Hierarchical MVC is the de-facto enterprise-level HMVC framework for CFML developers. It's professionally backed, conventions-based, modular, highly extensible, and productive.
ColdBox has the most extensive documentation of all modern CFML frameworks. ๐
If you don't like reading, try our video learning platform: CFCasts ๐ฅ
ColdBox is a professional open-source project funded by the community and Ortus Solutions, Corp.
Become a sponsor: https://patreon.com/ortussolutions โค๏ธ
Apache License, Version 2.0.
Problem: Installed a module with web UI (like
cbdebugger
) but getting 404 errors.
Solution: Add a CommandBox alias in server.json
:
"aliases": {
"/cbdebugger": "./modules/cbdebugger"
}
Then restart: box server restart
Problem: Tests fail with "Handler not found" or "Model not found".
Solution: Ensure your test component has appMapping="/app"
:
component extends="coldbox.system.testing.BaseTestCase" appMapping="/app" {
Problem: Trying to access
/app/handlers/Main.cfc
directly.
Solution: This is by design! Application code in
/app
is NOT web-accessible for security. All requests
must go through /public/index.cfm
.
This template is designed for:
To specify your engine in server.json
:
"app": {
"cfengine": "boxlang@be" // For BoxLang
// OR
"cfengine": "adobe@2023" // For Adobe ColdFusion
}
If you're migrating from the default ColdBox template to Modern:
/handlers
,
/models
, /views
, etc. to /app/
/public/Application.cfc
as referenceserver.json
for modulesappMapping="/app"
in test components/public/includes/
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
"I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
$
box install cbtemplate-modern