Create Custom Form Rules and Behaviors with Content Type Form Controllers
Applicable to CrafterCMS 4.x
Russ Danner

In CrafterCMS, there are many points in a content item’s lifecycle: create, update, delete, copy, paste, and duplicate, where you might want something special to happen automatically. That’s precisely what content form controllers are for.
Form controllers are scriptable lifecycle event handlers that let you run custom logic either:
-
On the client side (in the form on load, on save and other events)
-
On the server side (during content write/delete operations in the backend)
Why Use Form Controllers?
Form controllers are ideal for scenarios that require automation or custom validation across multiple fields, or when external information is needed before publishing content. Examples include:
-
Synthesizing new values from existing fields
e.g., automatically generating a slug from a title. -
Tying two fields together
e.g., If one field changes, update another field dynamically. -
Validating content
e.g., Querying a remote system to verify a value before saving. -
Blocking saves if the custom validation rule fails.
Simple Client-Side Example
Imagine you want to ensure the Internal Name always ends with a star (*
):
-
You’d write a
form-controller.js
script for the relevant content type. -
In the
onBeforeSave()
method, you’d check if the value ends with*
; if not, append it. -
This all happens before the save request is sent to the server.
The result? Users save their content normally, but your rule ensures the formatting is always correct.
You can enable a client-side controller via a <controller>true</controller>
tag in the type’s config XML by adding the form-controller.js
Note that the last line in the script informs the plugin system that the controller is loaded and associates the name of the content type (-controller) with the class.
Simple Server-Side Example
On the backend, a controller.groovy
file lets you:
-
Inspect the content, user, path, type, and lifecycle operation (create/update/move/etc).
-
Run logic before the save completes, such as integration calls, data checks, or transformations.
-
Block, modify, or enhance the save process without touching the UI.
A simple starter script might just log the lifecycle event type (create
, update
, etc.) to the server console, but the possibilities extend far beyond that.
Server-side controllers are automatically wired in through their controller.groovy
.
📺 Watch the Demo Video:
For a full walkthrough with live examples of both client-side and server-side controllers, check out our video here: Content Form Controllers in CrafterCMS.
Related Posts

The CrafterCMS Content Modeling Guide: A Deep Dive for Developers

Amanda Lee

Unlocking Visibility: Structured Data Markup for Content Pros & Devs

Amanda Jones

Why AI Won’t Replace SEO: What Content Editors Should Know

Amanda Lee

AI-First Content Management: Transforming Enterprise Content Workflows

Amanda Jones