```
## Collection Templates
Templates in `templates/` are used with `cb.renderCollection()`. Each template receives:
- `_counter` — Current iteration index (1-based)
- `_items` — Total number of items in the collection
- `{templateName}` — The object being rendered (e.g., `entry`, `category`, `comment`)
### templates/entry.cfm
```cfml
```
## Widget Overrides
Place widgets in `widgets/` to override core widgets of the same name:
```cfml
component extends="contentbox.models.ui.BaseWidget" singleton {
function init(){
setName( "Menu" );
setVersion( "1.0.0" );
setDescription( "Custom menu widget override" );
}
any function renderIt( string menuName = "main" ){
// Custom menu rendering
}
}
```
## The CB Helper
The `cb` helper (`CBHelper@contentbox`) is the primary API for theme development:
```cfml
#cb.site()#
#cb.siteURL()#
#cb.siteName()#
#cb.getContent()#
#cb.entryURL( entry )#
#cb.pageURL( page )#
#cb.categoryURL( category )#
#cb.getThemeSetting( "name" )#
#cb.widget( "WidgetName", { arg1 = "value" } )#
#cb.renderCollection( template = "entry", collection = query )#
#cb.renderView( view = "partial" )#
#cb.menu( "main" )#
#cb.rssURL()#
#cb.rssCommentsURL()#
#cb.searchURL()#
#cb.searchURL( "query" )#
#cb.subscribeURL()#
#cb.unsubscribeURL()#
```
## Theme Discovery and Registration
ContentBox discovers themes from two locations:
1. **Core themes**: `modules/contentbox/themes/`
2. **Custom themes**: `modules_app/contentbox-custom/_themes/`
The `ThemeService@contentbox` builds the theme registry at startup. Custom themes override core themes of the same name.
## Theme Switching
Themes can be switched per-site via admin settings. The active theme is resolved at runtime:
```cfml
property name="themeService" inject="themeService@contentbox";
var activeTheme = themeService.getActiveTheme();
var themePath = themeService.getThemePath( activeTheme );
```
## Best Practices
1. **Always include mandatory files**: `Theme.cfc`, `blog.cfm`, `pages.cfm`, `index.cfm`, `entry.cfm`, `page.cfm`, `archives.cfm`, `error.cfm`
2. **Use `cb` helper** for all URL generation — never hardcode paths
3. **Use collection templates** for iterating over entries, categories, comments
4. **Group theme settings** logically using the `group` key
5. **Provide `screenshot.png`** for admin theme preview
6. **Use `loadHelpFile()`** for field help that reads from `includes/help/`
7. **Keep theme-specific widgets** in the theme's `widgets/` folder
8. **Test with multiple content types** — entries, pages, categories, search results
9. **Use `prc` scope** for handler-passed data in views
10. **Follow CFML compatibility** — target Lucee 5+ and Adobe ColdFusion 2018+
## 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.
Key CFML considerations:
- Use `` for variable interpolation in CFML templates
- Use `structKeyExists()` for safe struct access
- Use `listContains()` for list operations
- Use `arrayLen()` for array length
- Use `dateFormat()` and `timeFormat()` for date formatting