agentsclimarketplace

Admin extension

Skill ColdBox/skills/contentbox-boxlang/admin-extension

Collection of skills for the ColdBox Platform and Claude Plugin

Install
npx -y skills add ColdBox/skills --skill admin-extension

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use this skill when extending the ContentBox admin UI with custom menus, views, interception points, editor integrations, workflows, and secure admin-only module behaviors.

SKILL.md

9.2 KB, as published. Nobody here has run it

ContentBox Admin Extension (BoxLang)

Extend the ContentBox admin interface using BoxLang. Add custom panels, modify existing screens, inject HTML into admin layouts, hook into content lifecycle events, and register new admin functionality.

Admin Module Overview

The admin module lives at modules/contentbox/modules/contentbox-admin/ with entry point cbadmin. It provides:

  • 30+ handlers for managing content, authors, settings, security, etc.
  • Admin layouts with consistent navigation and UI
  • Interceptors for request processing, 2FA enforcement, menu management
  • Interception points for extending every part of the admin UI

Admin Extension Points

1. Layout HTML Injection

Inject custom HTML into the admin layout at specific points:

Interception PointLocation
cbadmin_beforeHeadEndBefore </head> tag
cbadmin_afterBodyStartAfter <body> tag
cbadmin_beforeBodyEndBefore </body> tag
cbadmin_footerAdmin footer area
cbadmin_beforeContentBefore main content area
cbadmin_afterContentAfter main content area
cbadmin_onTagLineTag line area
cbadmin_onTopBarTop navigation bar

Example: Inject Custom CSS/JS

// interceptors/AdminAssets.bx
component {

	function configure(){
	}

	function onCbadmin_beforeHeadEnd( event, data, buffer, rc, prc ){
		buffer.append( '<link rel="stylesheet" href="/modules/mymodule/includes/css/admin.css">' )
	}

	function onCbadmin_beforeBodyEnd( event, data, buffer, rc, prc ){
		buffer.append( '<script src="/modules/mymodule/includes/js/admin.js"></script>' )
	}

}

2. Content Editor Extension

Extend the content editor (entry/page editing screens):

Interception PointLocation
cbadmin_contentEditorSidebarSidebar area
cbadmin_contentEditorSidebarAccordionSidebar accordion sections
cbadmin_contentEditorSidebarFooterBottom of sidebar
cbadmin_contentEditorFooterEditor footer
cbadmin_contentEditorInBodyInside editor body
cbadmin_contentEditorNavEditor navigation
cbadmin_contentEditorNavContentEditor nav content

Example: Add Custom Sidebar Panel

// interceptors/EditorSidebar.bx
component {

	function configure(){
	}

	function onCbadmin_contentEditorSidebarAccordion( event, data, buffer, rc, prc ){
		content = '
			<div class="accordion-section">
				<h4>My Custom Panel</h4>
				<div class="accordion-content">
					<p>Custom panel content here</p>
				</div>
			</div>
		'
		buffer.append( content )
	}

}

3. Content Lifecycle Events

Hook into content save, remove, and status change events:

Entry Events

PointWhen
cbadmin_preEntrySaveBefore entry is saved
cbadmin_postEntrySaveAfter entry is saved
cbadmin_preEntryRemoveBefore entry is deleted
cbadmin_postEntryRemoveAfter entry is deleted
cbadmin_onEntryStatusUpdateWhen entry status changes

Page Events

PointWhen
cbadmin_prePageSaveBefore page is saved
cbadmin_postPageSaveAfter page is saved
cbadmin_prePageRemoveBefore page is deleted
cbadmin_postPageRemoveAfter page is deleted
cbadmin_onPageStatusUpdateWhen page status changes

Example: Post-Save Hook

// interceptors/EntryAudit.bx
component {

	property name="log" inject="logbox:logger:EntryAudit"

	function configure(){
	}

	function onCbadmin_postEntrySave( event, data, buffer, rc, prc ){
		// data.entry contains the saved entry
		entry = data.entry
		log.info( "Entry saved: #{entry.getTitle()}# by #{entry.getAuthor().getUsername()}#" )

		// Could also trigger external API, send notifications, etc.
	}

}

4. Author Extension

Extend author management screens:

PointLocation
cbadmin_UserPreferencePanelUser preferences panel
cbadmin_onAuthorEditorNavAuthor editor navigation
cbadmin_onAuthorEditorContentAuthor editor content area
cbadmin_onAuthorEditorSidebarAuthor editor sidebar
cbadmin_onAuthorEditorActionsAuthor editor action buttons
cbadmin_onNewAuthorFormNew author form
cbadmin_onNewAuthorActionsNew author form actions
cbadmin_preNewAuthorSaveBefore new author saved
cbadmin_postNewAuthorSaveAfter new author saved
cbadmin_onAuthorPasswordChangeWhen author password changes
cbadmin_preAuthorPreferencesSaveBefore preferences saved
cbadmin_postAuthorPreferencesSaveAfter preferences saved

Example: Add Custom Author Field

// interceptors/AuthorExtension.bx
component {

	property name="authorService" inject="authorService@contentbox"

	function configure(){
	}

	function onCbadmin_onAuthorEditorSidebar( event, data, buffer, rc, prc ){
		content = '
			<div class="form-group">
				<label>Department</label>
				<input type="text" name="department"
					value="#{prc.author?.getDepartment() ?: ''}#"
					class="form-control">
			</div>
		'
		buffer.append( content )
	}

	function onCbadmin_postAuthorSave( event, data, buffer, rc, prc ){
		// Save custom field
		if( structKeyExists( rc, "department" ) ){
			data.author.setDepartment( rc.department )
			authorService.save( data.author )
		}
	}

}

5. Dashboard Extension

Add content to the admin dashboard:

PointLocation
cbadmin_onDashboardDashboard main area
cbadmin_preDashboardContentBefore dashboard content
cbadmin_postDashboardContentAfter dashboard content
cbadmin_preDashboardSideBarBefore dashboard sidebar
cbadmin_postDashboardSideBarAfter dashboard sidebar
cbadmin_onDashboardTabNavDashboard tab navigation
cbadmin_preDashboardTabContentBefore tab content
cbadmin_postDashboardTabContentAfter tab content

6. Admin Menu Registration

Register custom menu items via cbadmin_onAdminMenuLoad:

// interceptors/AdminMenu.bx
component {

	function configure(){
	}

	function onCbadmin_onAdminMenuLoad( event, data, buffer, rc, prc ){
		// data.menuItems is the array of menu items
		arrayAppend( data.menuItems, {
			name       : "My Module",
			link       : event.buildLink( "cbadmin/myModule" ),
			icon       : "star",
			permission : "MYMODULE_ACCESS",
			order      : 50
		} )
	}

}

Registering Admin Interceptors

Register your interceptors in your module's ModuleConfig.bx:

// ModuleConfig.bx
interceptors = [
	{
		class : "mymodule.interceptors.AdminAssets",
		name  : "AdminAssets@mymodule"
	},
	{
		class : "mymodule.interceptors.EditorSidebar",
		name  : "EditorSidebar@mymodule"
	},
	{
		class : "mymodule.interceptors.EntryAudit",
		name  : "EntryAudit@mymodule"
	}
]

Creating Custom Admin Handlers

Extend baseHandler for admin handlers:

// handlers/MyModule.bx
component extends="contentbox.modules.contentbox-admin.handlers.baseHandler" singleton {

	function index(){
		prc.pageTitle = "My Module"
		setView( "myModule/index" )
	}

	function settings(){
		prc.pageTitle = "My Module Settings"
		prc.settings  = settingService.getSettings()
		setView( "myModule/settings" )
	}

}

Admin Routes

Define routes in your module's ModuleConfig.bx:

routes = [
	{ pattern : "/cbadmin/myModule", handler : "myModule", action : "index" },
	{ pattern : "/cbadmin/myModule/settings", handler : "myModule", action : "settings" },
	{ pattern : "/cbadmin/myModule/:action", handler : "myModule" }
]

Admin Security

Admin handlers inherit security from the admin firewall. Configure permissions:

// In your module's ModuleConfig.bx
settings.cbsecurity = {
	firewall : {
		rules : {
			provider : {
				source     : "model",
				properties : {
					model  : "securityRuleService@contentbox",
					method : "getSecurityRules"
				}
			}
		}
	}
}

Best Practices

  1. Use interception points — don't modify core admin files
  2. Register interceptors in your module's ModuleConfig.bx
  3. Extend baseHandler for admin handlers
  4. Use prc scope for passing data to admin views
  5. Check permissions before rendering admin content
  6. Use buffer.append() for HTML injection interceptors
  7. Follow admin UI patterns — match existing styling and structure
  8. Test with all engines — Lucee, Adobe CF, BoxLang
  9. Use provider: injection to avoid circular dependencies
  10. Document custom interception points in your module

Engine Compatibility

This skill targets BoxLang engine. For CFML-specific syntax (Lucee 5+, Adobe ColdFusion 2018+), see the CFML variant of this skill.

Key BoxLang advantages:

  • Cleaner script syntax without <cfcomponent> / <cffunction> tags
  • No parentheses needed for zero-argument function calls
  • #{...}# for inline expression output in .bx templates
  • Modern syntax: ?: null coalescing, ?. safe navigation
  • Native support for modern data structures

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.