Skip to main content

Form Schema

The FormSchema system provides a structured JSON representation of forms. It enables programmatic form manipulation, REST API field management, and round-tripping between HTML and structured data.

Schema Structure

{
    "version": 1,
    "fields": [
        {
            "name": "email",
            "type": "email",
            "label": "Email Address",
            "placeholder": "you@example.com",
            "required": true,
            "position": 0,
            "validation": { "pattern": "^[^@]+@[^@]+$" },
            "conditions": [],
            "attributes": { "autocomplete": "email" }
        },
        {
            "name": "message",
            "type": "textarea",
            "label": "Your Message",
            "placeholder": "Tell us more...",
            "required": false,
            "position": 1
        }
    ],
    "layout": {
        "type": "single"
    },
    "form_settings": {}
}

Top-Level Properties

Property Type Description
version int Schema format version (currently 1)
fields Field[] Ordered array of field definitions
layout object Layout configuration
form_settings object Schema-level form settings

Layout Types

Type Description
single Standard single-page form
multi-step Multi-step wizard with navigation
conversational One question at a time (fullscreen)

Field Object

Each field has these properties:

Property Type Required Default Description
name string Yes Unique identifier (maps to input name)
type string Yes text Field type (see types below)
label string No "" Human-readable label
placeholder string No "" Placeholder text
default_value string No "" Pre-filled value
required bool No false Whether the field is required
css_class string No "" CSS classes for the field
description string No "" Help text shown below the field
options array No [] Options for select/radio/checkbox
validation object No {} Validation rules (min, max, pattern)
conditions array No [] Conditional visibility rules
attributes object No {} HTML attributes
position int No 0 Display order (0-based)
group string No null Step or group name

Field Types

Input types: text, email, url, tel, number, date, time, datetime-local, password, color, range, hidden

Complex types: textarea, select, radio, checkbox, file

Composite types: name, address, consent, rating

Layout types: container, fieldset, heading, paragraph, divider

Action types: submit

Options Format

For select, radio, and checkbox fields:

{
    "name": "priority",
    "type": "select",
    "options": [
        { "value": "low", "label": "Low Priority" },
        { "value": "medium", "label": "Medium Priority" },
        { "value": "high", "label": "High Priority" }
    ]
}

Validation Rules

{
    "name": "age",
    "type": "number",
    "validation": {
        "min": 18,
        "max": 120,
        "pattern": "^[0-9]+$"
    }
}

Conditional Logic

{
    "name": "other_reason",
    "type": "textarea",
    "conditions": [
        {
            "field": "reason",
            "operator": "equals",
            "value": "other"
        }
    ]
}

Storage

Schemas are stored as post meta on the form post:

Meta key: _cf_form_schema
Meta value: JSON array (version, fields, layout, form_settings)

PHP API

FormSchema Class

use Core_Forms\Schema\FormSchema;

// Load from database
$schema = FormSchema::load( $form_id );

// Create from array
$schema = FormSchema::from_array( $data );

// Check if schema exists
if ( FormSchema::exists( $form_id ) ) { ... }

// Save to database
$schema->save( $form_id );

// Delete
FormSchema::delete( $form_id );

Working with Fields

use Core_Forms\Schema\Field;

// Add a field
$field = Field::from_array( [
    'name'     => 'phone',
    'type'     => 'tel',
    'label'    => 'Phone',
    'required' => false,
] );
$schema->add_field( $field );

// Get a field
$email = $schema->get_field( 'email' );

// Remove a field
$schema->remove_field( 'phone' );

// Get only input fields (excludes headings, dividers, submit)
$inputs = $schema->get_input_fields();

// Get required field names
$required = $schema->get_required_field_names();

Convert to Array/JSON

$array = $schema->to_array();
$json  = wp_json_encode( $schema ); // Uses JsonSerializable

MarkupParser: HTML to Schema

The MarkupParser class converts existing HTML form markup into a structured schema:

use Core_Forms\Schema\MarkupParser;

$parser = new MarkupParser();
$schema = $parser->parse( $html_markup );

Use the REST API to trigger parsing:

POST /wp-json/cf/v1/forms/{id}/schema/generate

SchemaRenderer: Schema to HTML

The SchemaRenderer class converts a schema back to HTML markup. The output can be filtered with cf_schema_markup:

$html = $renderer->render( $schema );
$html = apply_filters( 'cf_schema_markup', $html, $schema, $form );

Related