---
name: contentbox-cfml-module-development
description: "Use this skill when building ContentBox modules, including ModuleConfig conventions, admin integration, interceptors, routes, migrations, ORM entities, dependency registration, and module lifecycle hooks."
applyTo: "**/*.{cfc,cfm,cfml}"
---
# ContentBox Module Development (CFML)
Build custom modules for ContentBox CMS using CFML. Modules are ColdBox modules that extend ContentBox functionality — adding new admin panels, API endpoints, widgets, interceptors, or content features.
## Module Architecture
ContentBox uses a layered module architecture:
| Layer | Path | Purpose |
|-------|------|---------|
| **Core** | `modules/contentbox/` | ContentBox engine (do not modify) |
| **Sub-modules** | `modules/contentbox/modules/` | Admin, API, UI, deps |
| **Custom** | `modules_app/contentbox-custom/` | User-owned customizations |
| **Standalone** | `modules/` | Independent ColdBox modules |
### Module Locations for Custom Code
| Type | Location |
|------|----------|
| Custom modules | `modules_app/contentbox-custom/_modules/` |
| Custom widgets | `modules_app/contentbox-custom/_widgets/` |
| Custom themes | `modules_app/contentbox-custom/_themes/` |
| Custom content | `modules_app/contentbox-custom/_content/` |
| Standalone modules | `modules/{moduleName}/` |
## ModuleConfig.cfc
Every module requires a `ModuleConfig.cfc` at its root:
```cfml
```
### ModuleConfig Properties
| Property | Description |
|----------|-------------|
| `title` | Module display name |
| `author` | Author name |
| `webURL` | Author/project website |
| `version` | Module version |
| `description` | Module description |
| `viewParentLookup` | Inherit views from parent modules (`true`/`false`) |
| `layoutParentLookup` | Inherit layouts from parent modules (`true`/`false`) |
| `entryPoint` | SES URL prefix for module routes |
| `modelNamespace` | WireBox DI namespace (e.g., `@mymodule`) |
| `cfmapping` | ColdFusion mapping for the module |
| `dependencies` | Array of required module names |
### ModuleConfig Methods
| Method | When Called | Purpose |
|--------|-------------|---------|
| `configure()` | Module registration | Define settings, routes, interceptors |
| `onLoad()` | After module loaded | Post-load initialization |
| `onUnload()` | Module unloaded | Cleanup resources |
| `onMissingMethod()` | Missing method calls | Dynamic method handling |
## Module Directory Structure
```
myModule/
├── ModuleConfig.cfc ← Module configuration
├── box.json ← ForgeBox/CommandBox metadata
├── handlers/ ← ColdBox event handlers
│ └── Home.cfc
├── models/ ← Business logic and entities
│ ├── services/
│ │ └── MyService.cfc
│ └── entities/
│ └── MyEntity.cfc
├── views/ ← View templates
│ └── home/
│ └── index.cfm
├── layouts/ ← Layout templates
│ └── layout.cfm
├── interceptors/ ← ColdBox interceptors
│ └── MyInterceptor.cfc
├── widgets/ ← ContentBox widgets
│ └── MyWidget.cfc
├── modules/ ← Nested sub-modules
│ └── subModule/
├── config/ ← Configuration files
│ └── Router.cfc
├── i18n/ ← Resource bundles
│ └── mymodule.properties
├── migrations/ ← Database migrations
│ └── 001_create_my_table.cfm
└── includes/ ← Static assets, help files
├── css/
├── js/
└── help/
```
## Creating an Admin Module
To add functionality to the ContentBox admin:
```cfml
```
### Admin Handler Pattern
```cfml
```
## Registering Admin Menu Items
Listen to `cbadmin_onAdminMenuLoad` to add menu items:
```cfml
```
## Registering 2FA Providers
Register custom two-factor authentication providers in `onLoad()`:
```cfml
```
## Registering Content Helpers
Inject mixins into all content objects:
```cfml
```
## Database Migrations
Use cfmigrations for schema changes:
```cfml
function up( schema, qb ){
schema.create( "my_table", function( table ){
table.increments( "id" ).primary();
table.string( "name" ).nullable( false );
table.timestamps();
} );
}
function down( schema, qb ){
schema.drop( "my_table" );
}
```
Run migrations:
```bash
box run-script contentbox:migrate
box run-script contentbox:migrate:up
```
## ORM Entities
Create persistent entities with ContentBox conventions:
```cfml
```
## Module Dependencies
Declare dependencies in `ModuleConfig.cfc`:
```cfml
```
## Accessing ContentBox Services
```cfml
```
## Interception Points
### Core ContentBox Interception Points
| Point | When Fired |
|-------|------------|
| `cb_onContentRendering` | Before content is rendered |
| `cb_onContentStoreRendering` | Before ContentStore content is rendered |
### Admin Interception Points
See the admin extension skill for the full list of `cbadmin_*` interception points.
## Best Practices
1. **Use `modules_app/contentbox-custom/_modules/`** for user-owned modules
2. **Declare dependencies** in `this.dependencies`
3. **Use namespace injection** — `@moduleName` for DI
4. **Follow ColdBox conventions** — handlers, models, views, layouts
5. **Use migrations** for database changes — never modify schema directly
6. **Extend base classes** — `BaseEntity`, `baseHandler`, `BaseWidget`
7. **Register interceptors** for admin menu, content lifecycle, etc.
8. **Use `provider:` injection** to avoid circular dependencies
9. **Include `box.json`** for ForgeBox distribution
10. **Test with all three engines** — Lucee, Adobe CF, BoxLang
## Engine Compatibility
This skill targets **CFML engines** (Lucee 5+, Adobe ColdFusion 2018+). For BoxLang-specific syntax and features, see the BoxLang variant of this skill.