Skip to content
Back to skills

Fluentform Custom Fields

ASecurity

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...

  • 22 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 5, 2026
developmentjavascriptjavaphpdebuggingapifrontendsecuritydocumentation

Works with

  • api

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 5, 2026

npx -y skills add Lonsdale201/wp-agent-skills --skill fluentform-custom-fields --agent claude-code

Installs 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 with every re-scan.

Security grade badge for Fluentform Custom Fields
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lonsdale201-fluentform-custom-fields/badge)](https://www.skillsdirectory.com/skills/lonsdale201-fluentform-custom-fields)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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`

Files in this skill

  • SKILL.md8.2 KB
  • agents/openai.yaml306 B
  • references/field-contract.md5.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…