Builds and reviews third-party Fluent Forms input fields with the Free-core BaseFieldManager API. Covers fluentform/loaded bootstrap, editor component schema, frontend rendering, input-name mapping, conditional logic, server-side normalization and validation, response formatting, accessibility, assets, and Free versus Pro feature boundaries. Use when code extends BaseFieldManager, adds fluentform/render_item_* or fluentform/validate_input_item_* hooks, creates a custom field for the form buil...
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Lonsdale201/wp-agent-skills --skill fluentform-custom-fields --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Fluentform Custom Fields?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lonsdale201-fluentform-custom-fields)More formats (shields.io, HTML) on the badges page.
---
name: fluentform-custom-fields
description: >-
Builds and reviews third-party Fluent Forms input fields with the Free-core
BaseFieldManager API. Covers fluentform/loaded bootstrap, editor component
schema, frontend rendering, input-name mapping, conditional logic, server-side
normalization and validation, response formatting, accessibility, assets, and
Free versus Pro feature boundaries. Use when code extends BaseFieldManager,
adds fluentform/render_item_* or fluentform/validate_input_item_* hooks, creates
a custom field for the form builder, or must make a field appear correctly in
entries, emails, feeds, and conditional rules.
metadata:
wp-skills-author: "Soczó Kristóf"
wp-skills-contact: "mailto:lonsdale201@hotmail.com"
wp-skills-plugin: "fluentform"
wp-skills-plugin-version-tested: "6.2.7"
wp-skills-wp-version-tested: "7.0.2"
wp-skills-php-min: "7.4"
wp-skills-last-updated: "2026-07-20"
---
# Fluent Forms custom fields
Build fields against the documented Free-core `BaseFieldManager` contract. Do
not copy a Pro component and accidentally make the extension depend on Pro.
Read [field-contract.md](references/field-contract.md) when implementing a new
field or debugging nested values, response rendering, editor settings, or Pro
feature detection.
## Availability contract
| Surface | Availability in 6.2.7 |
|---|---|
| `FluentForm\App\Services\FormBuilder\BaseFieldManager` | Free |
| Editor registration, frontend render hook, parser input type, conditional support | Free |
| Element input/validation/response filters | Free |
| Phone, range slider, NPS, ranking, dynamic field, chained select, repeater, rich text, file upload | Pro implementations |
The Pro fields demonstrate the same Free base class. Referencing their element
keys, JavaScript, uploader, data-source, or server classes is still Pro-only.
## Workflow
1. Inspect the installed versions and feature-detect every class or constant used.
2. Choose a globally unique, lowercase element key and a configurable input
`attributes.name`; never use the element key as a permanent business ID.
3. Bootstrap on `fluentform/loaded` and instantiate the field once.
4. Return a complete editor component with `element`, `attributes`, `settings`,
and `editor_options`.
5. Render with the inherited markup helpers so labels, error placement,
conditional logic, repeated form instances, and accessibility remain intact.
6. Normalize before rule validation, validate on the server, then add a separate
display formatter for entries/emails.
7. Test editor insertion, saved/reloaded configuration, classic and
conversational rendering, valid/invalid submission, conditional visibility,
entry display, email/feed value, and two instances of the same form.
## Bootstrap and field skeleton
```php
use FluentForm\App\Services\FormBuilder\BaseFieldManager;
use FluentForm\Framework\Helpers\ArrayHelper as Arr;
add_action('fluentform/loaded', static function (): void {
if (!class_exists(BaseFieldManager::class)) {
return;
}
new Acme_Order_Code_Field();
});
final class Acme_Order_Code_Field extends BaseFieldManager
{
public function __construct()
{
parent::__construct(
'acme_order_code',
__('Order code', 'acme-addon'),
['order', 'reference', 'code'],
'advanced'
);
}
public function getComponent()
{
return [
'index' => 20,
'element' => $this->key,
'attributes' => [
'type' => 'text',
'name' => 'acme_order_code',
'value' => '',
'class' => '',
'placeholder' => '',
],
'settings' => [
'label' => __('Order code', 'acme-addon'),
'admin_field_label' => '',
'label_placement' => '',
'help_message' => '',
'container_class' => '',
'validation_rules' => [
'required' => [
'value' => false,
'message' => __('This field is required.', 'acme-addon'),
],
],
'conditional_logics' => [],
],
'editor_options' => [
'title' => __('Order code', 'acme-addon'),
'icon_class' => 'ff-edit-text',
'template' => 'inputText',
],
];
}
public function render($data, $form)
{
$data['attributes']['id'] = $this->makeElementId($data, $form);
$data['attributes']['class'] = trim(
'ff-el-form-control ' . Arr::get($data, 'attributes.class', '')
);
$input = '<input ' . $this->buildAttributes($data['attributes'], $form) . '>';
$html = $this->buildElementMarkup($input, $data, $form);
$this->printContent(
'fluentform/rendering_field_html_' . $this->key,
$html,
$data,
$form
);
}
}
```
Keep `render()` output escaped. The inherited helpers escape attributes and
produce Fluent Forms-compatible wrappers; they do not make arbitrary custom HTML
or JavaScript safe.
## Normalize and validate
```php
add_filter(
'fluentform/input_data_acme_order_code',
static fn($value) => is_string($value) ? strtoupper(trim($value)) : $value,
10,
1
);
add_filter(
'fluentform/validate_input_item_acme_order_code',
static function ($error, $field, $formData, $fields, $form, $errors = []) {
$name = (string) ($field['name'] ?? '');
$value = (string) ($formData[$name] ?? '');
if ($value !== '' && !preg_match('/^[A-Z0-9-]{6,32}$/', $value)) {
$error = is_array($error) ? $error : ($error ? [$error] : []);
$error['acme_format'] = __('Use 6–32 letters, numbers, or dashes.', 'acme-addon');
}
return $error;
},
10,
6
);
```
Scope form-specific rules with `(int) $form->id`. Never rely only on browser
validation. Do not add raw request keys to `fluentform/white_listed_fields` merely
to make a field persist; a registered input type and a valid `attributes.name`
are the correct path.
## Response formatting
Use response formatting only for display. Preserve the stored machine value.
```php
add_filter(
'fluentform/response_render_acme_order_code',
static function ($response, $field, $formId, $isHtml) {
$value = (string) $response;
return $isHtml ? esc_html($value) : $value;
},
10,
4
);
```
## Critical rules
- Treat `attributes.name` as the key connecting browser data, `$formData`, the
submission `response` JSON, entry details, smart codes, and feed mappings.
- Keep filters pure and deterministic; rendering and formatting can occur more
than once in a request.
- Register scripts/styles only when the target form contains the field and use
unique handles. Do not enqueue Pro assets from a Free-only addon.
- Support arrays intentionally. A scalar-looking renderer or validator is not
automatically safe for repeaters, containers, or multi-value inputs.
- Do not use the unrelated `FluentForm\App\Modules\Component\BaseComponent` API
as the default extension path; `BaseFieldManager` is the documented and
core/Pro-used field manager in 6.2.7.
## Cross-references
- Use `fluentform-submission-lifecycle` for hook timing and transformations.
- Use `fluentform-entries-data` for stored response and entry-detail semantics.
- Use `wp-security-audit` when the custom renderer outputs complex HTML.
## References
- Official Base Field Manager documentation: <https://developers.fluentforms.com/api/classes/base-field-manager/>
- Verified Free source paths:
- `fluentform/app/Services/FormBuilder/BaseFieldManager.php`
- `fluentform/app/Services/FormBuilder/Components/BaseComponent.php`
- `fluentform/app/Services/Parser/Form.php`
- `fluentform/app/Services/Form/FormValidationService.php`
- Verified Pro examples, required only when their features are used:
- `fluentformpro/src/Components/RangeSliderField.php`
- `fluentformpro/src/Components/DynamicField/DynamicField.php`
- `fluentformpro/src/Components/RepeaterField.php`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!