1- # WordPress Register Setting Fields
1+ # Register Setting Fields
22
3- Settings pages for the WordPress admin, from a field configuration.
3+ A settings page from a list of fields — the menu, the tabs, the saving and
4+ the sanitising included.
45
5- Registration, rendering, sanitization and the Settings API are handled; you describe the fields. Every type comes from
6- [ wp-field-kit] ( https://github.com/arraypress/wp-field-kit ) , so the same configuration renders the same control here, in
7- a metabox, on a term screen or in a flyout.
6+ ## What it does
87
9- ## Features
8+ A settings screen in WordPress is ` add_menu_page ` , ` register_setting ` ,
9+ ` add_settings_section ` , ` add_settings_field ` and a sanitise callback per
10+ field, repeated until it works. Most of it is the same every time, and the
11+ part that varies is just the list of fields.
1012
11- - Every field type the kit has — sixty-odd, from text to a repeater to an email editor
12- - Tabs and sections, with the tab remembered in the URL
13- - A branded header with a logo, badge and whatever you want beside it
14- - Conditional fields, encrypted values, and constants that override an option
15- - Reset, export and import, when you want them
16- - Values readable through helpers that know what a field meant, not just what it stored
13+ This takes the list. The menu, the tabs, the form, the nonce, the saving and
14+ the per-type sanitising follow from it.
1715
18- ## Requirements
16+ ## Features
1917
20- - PHP 7.4+
21- - WordPress 5.8+
18+ * Get a settings page from a list of fields, with no ` add_settings_field ` calls
19+ * Group fields into tabs and sections, saving one tab without touching others
20+ * Read and write a value by name, without knowing how the option is shaped
21+ * Sanitise per field type, rather than writing a callback for each
22+ * Encrypt a field, so an API key is not stored in the clear
23+ * Export, import and reset from Screen Options
24+ * Show a field only when another is set
2225
2326## Installation
2427
@@ -30,175 +33,35 @@ composer require arraypress/wp-register-setting-fields
3033
3134``` php
3235register_setting_fields( 'my_plugin', [
33- 'page_title' => __( 'My Plugin Settings', 'my-plugin' ),
34- 'menu_title' => __( 'My Plugin', 'my-plugin' ),
35- 'parent_slug' => 'options-general.php',
36- 'fields' => [
37- 'site_name' => [ 'type' => 'text', 'label' => __( 'Site name', 'my-plugin' ) ],
38- 'enable_feature' => [ 'type' => 'toggle', 'label' => __( 'Enable feature', 'my-plugin' ) ],
39- 'items_per_page' => [
40- 'type' => 'number',
41- 'label' => __( 'Items per page', 'my-plugin' ),
42- 'min' => 1,
43- 'max' => 100,
44- ],
45- ],
36+ 'page_title' => __( 'My Plugin Settings', 'my-plugin' ),
37+ 'menu_title' => __( 'My Plugin', 'my-plugin' ),
38+ 'parent_slug' => 'options-general.php',
39+ 'fields' => [
40+ 'site_name' => [ 'type' => 'text', 'label' => __( 'Site name', 'my-plugin' ) ],
41+ 'enable_feature' => [ 'type' => 'toggle', 'label' => __( 'Enable feature', 'my-plugin' ) ],
42+ 'items_per_page' => [
43+ 'type' => 'number',
44+ 'label' => __( 'Items per page', 'my-plugin' ),
45+ 'min' => 1,
46+ 'max' => 100,
47+ ],
48+ ],
4649] );
4750```
4851
49- Reading them back :
52+ Then reading one, anywhere :
5053
5154``` php
5255$name = get_setting_field_value( 'my_plugin', 'site_name' );
53-
54- if ( is_setting_on( 'my_plugin', 'enable_feature' ) ) {
55- // ...
56- }
57- ```
58-
59- ## Registration
60-
61- ``` php
62- register_setting_fields( 'my_plugin', [
63- 'page_title' => __( 'My Plugin Settings', 'my-plugin' ),
64- 'menu_title' => __( 'My Plugin', 'my-plugin' ),
65- 'menu_slug' => 'my-plugin',
66- 'parent_slug' => 'options-general.php',
67- 'capability' => 'manage_options',
68- 'option_name' => 'my_plugin',
69- 'icon' => 'dashicons-admin-generic',
70- 'position' => null,
71- 'submit_button' => true,
72- 'reset_button' => false,
73- 'export_import' => false,
74- 'tabs' => [ /* ... */ ],
75- 'sections' => [ /* ... */ ],
76- 'fields' => [ /* ... */ ],
77- ] );
78- ```
79-
80- | Key | What it does |
81- | --- | --- |
82- | ` page_title ` / ` menu_title ` | The page's heading and its menu entry. |
83- | ` menu_slug ` | The page slug. Defaults to the id. |
84- | ` parent_slug ` | Where it sits. A top-level menu when empty. |
85- | ` capability ` | Who may see it. Defaults to ` manage_options ` . |
86- | ` option_name ` | The option every value is stored in. Defaults to the id. |
87- | ` option_group ` | The Settings API group. Defaults to ` {id}_group ` . |
88- | ` constant_prefix ` | Constants that override stored values. Defaults to ` {option_name}_ ` . |
89- | ` header_title ` , ` logo ` , ` badge ` | A branded header instead of the plain one. |
90- | ` icon ` , ` position ` | Menu icon and position, for a top-level page. |
91- | ` submit_button ` | Whether to draw one. |
92- | ` reset_button ` | A "restore defaults" button. |
93- | ` export_import ` | Buttons to download and upload the settings as JSON. |
94- | ` help_tabs ` , ` help_sidebar ` | Contextual help, in core's own panel. |
95-
96- ## Tabs and sections
97-
98- A field says which tab and which section it belongs to. Both are optional and can be mixed.
99-
100- ``` php
101- register_setting_fields( 'my_plugin', [
102- 'tabs' => [
103- 'general' => __( 'General', 'my-plugin' ),
104- 'advanced' => __( 'Advanced', 'my-plugin' ),
105- ],
106- 'sections' => [
107- 'branding' => [
108- 'title' => __( 'Branding', 'my-plugin' ),
109- 'description' => __( 'How it looks.', 'my-plugin' ),
110- ],
111- ],
112- 'fields' => [
113- 'site_name' => [
114- 'type' => 'text',
115- 'label' => __( 'Site name', 'my-plugin' ),
116- 'tab' => 'general',
117- 'section' => 'branding',
118- ],
119- 'debug' => [
120- 'type' => 'toggle',
121- 'label' => __( 'Debug mode', 'my-plugin' ),
122- 'tab' => 'advanced',
123- ],
124- ],
125- ] );
126- ```
127-
128- ## Conditional fields
129-
130- ``` php
131- 'fields' => [
132- 'mode' => [
133- 'type' => 'select',
134- 'label' => __( 'Mode', 'my-plugin' ),
135- 'options' => [ 'auto' => __( 'Automatic', 'my-plugin' ), 'manual' => __( 'Manual', 'my-plugin' ) ],
136- ],
137- 'api_key' => [
138- 'type' => 'password',
139- 'label' => __( 'API key', 'my-plugin' ),
140- 'depends' => [ 'mode' => 'manual' ],
141- ],
142- ],
14356```
14457
145- The field is removed from the tab order when hidden, not merely made invisible.
58+ Field types come from ` arraypress/wp-field-kit ` , so anything it renders can go
59+ in a settings page.
14660
147- ## Encrypted values
148-
149- ``` php
150- 'api_secret' => [
151- 'type' => 'password',
152- 'label' => __( 'API secret', 'my-plugin' ),
153- 'encrypted' => true,
154- ],
155- ```
156-
157- Stored encrypted, refused REST exposure, and decrypted on the way back out through ` get_setting_field_value() ` .
158-
159- ## Constants
160-
161- Any value can be overridden by a constant, which is how a secret stays out of the database on a production install.
162-
163- ``` php
164- // In wp-config.php:
165- define( 'MY_PLUGIN_API_KEY', 'sk-live-...' );
166- ```
167-
168- ` get_setting_field_value( 'my_plugin', 'api_key' ) ` returns the constant, and the field renders read-only with a note
169- saying where the value came from.
170-
171- ## Reading values
172-
173- | Function | Returns |
174- | --- | --- |
175- | ` get_setting_field_value( $id, $key, $fallback = null ) ` | One value, with its default and any constant applied. |
176- | ` get_all_setting_values( $id ) ` | Everything, keyed by field. |
177- | ` is_setting_on( $id, $key ) ` | Whether a toggle or checkbox is on. |
178- | ` is_setting_enabled( $id, $key, $option ) ` | Whether an option is among a multiple field's values. |
179- | ` get_setting_field_list( $id, $key ) ` | A list field's values as an array. |
180- | ` get_setting_field_ids( $id, $key ) ` | A relational field's ids, as integers. |
181- | ` get_setting_field_page_url( $id, $key ) ` | The permalink of a page a field points at. |
182- | ` is_setting_field_page( $id, $key ) ` | Whether the current request is that page. |
183- | ` update_setting_field_value( $id, $key, $value ) ` | Write one, sanitized by its own type. |
184- | ` delete_setting_field_value( $id, $key ) ` | Remove one, so it falls back to its default. |
185-
186- Email and licence fields have their own: ` get_setting_fields_email() ` , ` is_setting_fields_email_enabled() ` ,
187- ` get_setting_field_license_status() ` , ` is_setting_field_license_active() ` .
188-
189- ## Custom sanitization
190-
191- A field's type sanitizes it. Supply a callback to replace that entirely:
192-
193- ``` php
194- 'slug' => [
195- 'type' => 'text',
196- 'label' => __( 'Slug', 'my-plugin' ),
197- 'sanitize_callback' => fn( $value ) => sanitize_title( $value ),
198- ],
199- ```
61+ ## Requirements
20062
201- The callback receives the raw value, not one the type has already cleaned.
63+ * PHP 8.3 or later
64+ * WordPress 7.1 or later
20265
20366## License
20467
0 commit comments