arraypress / wp-field-kit
One field engine — type registry, accessible renderers, sanitizers, conditional logic and REST search — shared by the wp-register-*-fields libraries.
Requires
- php: >=8.3
Requires (Dev)
- phpcompatibility/phpcompatibility-wp: ^2.1
- phpunit/phpunit: ^12.0
- squizlabs/php_codesniffer: ^3.13.5
- wp-coding-standards/wpcs: ^3.4
README
Render, sanitise and store an admin form field — once, so nothing has to render one again.
What it does
Every library that puts a field on a screen ends up writing the same three
things: the markup, the sanitising, and the reading and writing of wherever
the value lives. Do it five times and you have five subtly different text
inputs, four of which forget esc_attr somewhere.
This is the one implementation. A field describes itself; the kit renders it, coerces what comes back by type, and reads and writes it through a context — post meta, term meta, an option, an array — so the same declaration works wherever the screen happens to be.
Features
- Render any of the field types below, escaped, with a label and description
- Sanitise on save by type, rather than a callback per field
- Store to post meta, term meta, user meta, an option or a plain array
- Show a field only when another has a given value
- Search posts, users or terms from one endpoint, whatever the field type
- Group fields into tabs or collapsible sections
- Sit two short fields on one line with
'width' => 'half' - Take an amount with its currency symbol inside the control
- Fold a repeater's rows away, each titled by one of its own fields
- Reorder a repeater by dragging its handle, or from the keyboard
- Encrypt a value at rest, for an API key
- Get told, under
WP_DEBUG, when a config key does nothing
Installation
composer require arraypress/wp-field-kit
Quick start
use ArrayPress\FieldKit\FieldSet; use ArrayPress\FieldKit\Context\OptionContext; $set = new FieldSet( [ 'site_name' => [ 'type' => 'text', 'label' => __( 'Site name', 'my-plugin' ) ], 'per_page' => [ 'type' => 'number', 'label' => __( 'Per page', 'my-plugin' ), 'min' => 1 ], ], new OptionContext( 'my_plugin' ), 'my_plugin' ); echo $set->render(); // Each value is coerced by its own type; a key you did not declare is dropped. $set->save( $_POST['my_plugin'] ?? [] );
Field types
Text and numeric
: text email url tel password hidden number range textarea code wysiwyg code_generator
Date, time and colour
: date time datetime color gradient date_range time_range
Choice
: select enhanced_select select_multiple checkbox toggle radio checkbox_group button_group card_choice
Relational — one search endpoint behind all of them
: post page user taxonomy ajax tags
Media
: image file file_url gallery files
Compound
: group repeater list key_value sortable providers dimensions amount_type flexible
Layout and display
: heading separator message html link clipboard oembed custom tab accordion icon nav_menu
Purpose-built
: license email_editor action_button
Requirements
- PHP 8.3 or later
- WordPress 7.1 or later
License
GPL-2.0-or-later