Form Actions API
For custom submission handling without writing a plugin, the canonical documentation recommends the built-in Webhook action with a service such as Zapier to route data to another app. Use this API when developing a reusable form action.
Create a subclass of BreakdanceFormsActionsAction, then register an instance after Breakdance loads. Your action appears under Actions After Submission in Form Builder:
add_action('init', function () {
if (!class_exists('\Breakdance\Forms\Actions\Action')
|| !function_exists('\Breakdance\Forms\Actions\registerAction')) {
return;
}
if (!class_exists('AcmeNoopFormAction', false)) {
class AcmeNoopFormAction extends BreakdanceFormsActionsAction
{
public static function name() { return 'Acme Test Action'; }
public static function slug() { return 'acme_test_action'; }
public static function proOnly() { return false; }
public function run($form, $settings, $extra)
{
return ['type' => 'success', 'message' => 'Test action completed.'];
}
}
}
BreakdanceFormsActionsregisterAction(new AcmeNoopFormAction());
});
Reload and select Acme Test Action. This example has no external effect.

Contract
| Method | Purpose |
|---|---|
Static name() |
Display label. |
Static slug() |
Stable unique identifier. |
controls() |
Optional action settings controls; defaults to an empty array. |
run($form, $settings, $extra) |
Performs the action after submission processing. |
Static proOnly() |
Controls the built-in availability flag; the example sets it to false. |
$form contains labels, value, originalValue, and advanced.id. Configuration is $settings['actions'][static::slug()]. $extra includes formId, postId, fields, uploads, files, ip, referer, userAgent, userId.
Return one ['type' => 'success'|'error', 'message' => '...'] record, despite the base annotation mentioning a list. The response message is included with the action result shown to administrators.
Helpers
BreakdanceFormsgetIdFromField($field)— Field identity.renderData($form, $content, $escapeHtml = false)— Replace field placeholders and{all_fields}; HTML escaping defaults off.addContext($section, $context)/getContext()— Diagnostics; omit credentials/private data.
Reject fields through validation hooks. For external actions, handle errors and uncertain retries without duplicating operations.
Submission Arguments
run($form, $settings, $extra) runs when the form is submitted.
$form
An array of fields containing their builder configuration and submitted values:
type— Field type.name— Field label.options— Available checkbox, radio, or select choices.value— Submitted value.originalValue— Original/default value.advanced.id— Configured field identifier.
$settings
The form's configured builder settings. Custom action settings are under $settings['actions'][static::slug()]. Define action controls with controls() when your action needs configurable values.
$extra
| Key | Value |
|---|---|
files |
Uploaded file information. |
uploads |
Upload processing data supplied by the current implementation. |
fields |
Submitted values keyed by field ID. |
formId |
Form ID. |
postId |
ID of the post containing the form. |
ip |
Submitter's IP address. |
referer |
Referrer URL. |
userAgent |
Browser user-agent string. |
userId |
Submitter's user ID, when applicable. |
Return Success or an Error
Perform the work in run(), then return a result. The official example logs a submission to a file:
public function run($form, $settings, $extra)
{
try {
$this->writeToFile($extra['formId'], $extra['fields']);
} catch (Exception $e) {
return ['type' => 'error', 'message' => $e->getMessage()];
}
return ['type' => 'success', 'message' => 'Submission logged to file'];
}
writeToFile() is an example extension method you must implement; it is not supplied by the base action. Return ['type' => 'error', 'message' => 'Could not write to file'] when your implementation fails.
Keep the Action in a Separate File
For a larger extension, put the class in my-action.php and load it only after the API is available:
add_action('init', function () {
if (!function_exists('BreakdanceFormsActionsregisterAction')
|| !class_exists('BreakdanceFormsActionsAction')) {
return;
}
require_once __DIR__ . '/my-action.php';
BreakdanceFormsActionsregisterAction(new MyAction());
});
Use this registration pattern instead of the inline-class example when your class is named MyAction and stored in that file. The current base class declares name() and slug() as static methods; the original GitHub reference shows older nonstatic signatures.
Register each action once. The current provider creates a fresh instance of the class with no constructor arguments, so do not require constructor arguments or rely on state assigned to the instance you pass to registerAction(). Read action configuration from $settings instead.