yipresser / wp-settings-api-helper
A helper class to simplify WordPress Settings and creation of Settings page in WP plugins.
Package info
github.com/yipresser/wp-settings-api-helper
pkg:composer/yipresser/wp-settings-api-helper
Requires
- php: >=7.2
README
An abstract class that simplifies the process of creating WordPress admin settings pages using the WordPress Settings API.
Installation
You can install this package via Composer:
composer require yipresser/wp-settings-api-helper
Alternatively, you can use this class in your WordPress plugins or themes to easily define settings sections, fields, and handle their saving process.
Usage
To use the helper, create a new class that extends Yipresser\WpSettingsApiHelper\WP_Settings_API_Helper.
1. Extend the Class and initialize the Settings
You need to define $settings_options for your database options and $settings_sections for the visual sections and fields you want to show on the page. These properties are protected, so set them inside your child class. Lastly, implement sanitize_settings() and run the setup() method.
namespace MyPlugin\Admin; use Yipresser\WpSettingsApiHelper\WP_Settings_API_Helper; class My_Settings extends WP_Settings_API_Helper { public function __construct() { add_action( 'admin_init', [ $this, 'init' ] ); } /** * Start the engine running. * * @return void */ public function init() { // Define your options $this->settings_options = [ [ 'option_group' => 'my_plugin_settings_group', 'option_name' => 'my_plugin_settings', // Optionally supply an already resolved option array: // 'option_value' => $this->options, // Optional args for register_setting(): // 'args' => [ 'sanitize_callback' => [$this, 'sanitize_settings'] ] ] ]; // Define your sections and fields $this->settings_sections = [ [ 'id' => 'my_plugin_general_section', 'title' => 'General Settings', 'description' => 'These are the general settings for the plugin.', 'menu_slug' => 'my_plugin_slug', // Slug of the settings page 'option_name' => 'my_plugin_settings', 'args' => [ 'before_section' => '<div class="%s">', 'after_section' => '</div>', 'section_class' => 'section-wrapper', ], 'fields' => [ [ 'type' => 'text', 'title' => 'API Key', 'id' => 'api_key', 'name' => 'api_key', 'default' => '', 'desc' => 'Enter your API key here.', ], [ 'type' => 'checkbox', 'title' => 'Enable Feature', 'id' => 'enable_feature', 'name' => 'enable_feature', 'label' => 'Check to enable', 'default' => 0, ] ] ] ]; $this->setup(); } /** * Sanitize settings before saving. * * @param array $option Saved options from the settings page. * * @return array */ public function sanitize_settings( $option ) { $sanitized = []; if ( isset( $option['api_key'] ) ) { $sanitized['api_key'] = sanitize_text_field( $option['api_key'] ); } $sanitized['enable_feature'] = ! empty( $option['enable_feature'] ) ? 1 : 0; return $sanitized; } }
Supplying Resolved Option Values
By default, the helper loads each section's values from WordPress using the section's option_name. If a client has already resolved an option array, including module-level defaults, it can pass that array through option_value:
$this->settings_options = [ [ 'option_group' => 'my_plugin_settings_group', 'option_name' => 'my_plugin_settings', 'option_value' => $this->options, 'args' => [ 'sanitize_callback' => [ $this, 'sanitize_settings' ], ], ], ];
The supplied array is used by every settings section with the matching option_name. Other options managed by the same settings class continue loading their own values from the WordPress database. An explicitly supplied empty array is also respected. Existing clients that omit option_value retain the original get_option() behavior.
2. Display the Settings Form
When rendering your options page HTML, call the render_settings_on_page() method so it can generate the settings form, fields, and submit button.
// Assuming this is inside your admin page callback function public function my_plugin_options_page() { echo '<div class="wrap">'; echo '<h1>My Plugin Options</h1>'; // Pass the menu_slug used in your $settings_sections $my_settings->render_settings_on_page( 'my_plugin_slug' ); echo '</div>'; }
Supported Field Types
The type key in your field configuration supports the following values:
texturlnumber(supportsmin,max, andstepattributes)emailpasswordtextarea(supports optionalrowsandcols)code-editor(supports optionalcode_type,code_theme,rows, andcols)select(requires achoicesarray['value' => 'Label']; supportsmultiple)radio(requires achoicesarray)checkbox(optionallabelfor text next to checkbox)checkboxes(requires achoicesarray)slider-checkboxdropdown_pagescolorrange(supportsmin,max, andstep, with a live output display)image(uses the WordPress media library; supportsimage_return)hiddencallback(requirescallbackand optionalparamkeys to render custom HTML)
Common field keys include:
id: HTML ID and settings field ID.name: key inside the saved option array.title: settings field label.default: fallback value when no option is saved.desc: optional field description. Basic HTML is allowed.class: optional CSS class.placeholder: optional placeholder for text-like fields.disabled: disables the input when truthy.
Example Select Field
[
'type' => 'select',
'title' => 'Select Mode',
'id' => 'mode',
'name' => 'mode',
'choices' => [
'light' => 'Light Mode',
'dark' => 'Dark Mode'
],
'default' => 'light'
]
Example Multiple Select Field
[
'type' => 'select',
'title' => 'Enabled Locations',
'id' => 'locations',
'name' => 'locations',
'multiple' => true,
'choices' => [
'header' => 'Header',
'footer' => 'Footer',
],
'default' => [ 'header' ],
]
When multiple is enabled, the helper appends [] to the generated field name and expects the saved value to be an array.
Example Color Field
[
'type' => 'color',
'title' => 'Accent Color',
'id' => 'accent_color',
'name' => 'accent_color',
'default' => '#2271b1',
]
Example Range Field
[
'type' => 'range',
'title' => 'Opacity',
'id' => 'opacity',
'name' => 'opacity',
'min' => 0,
'max' => 1,
'step' => 0.1,
'default' => 0.8,
]
Example Image Field
[
'type' => 'image',
'title' => 'Logo',
'id' => 'logo',
'name' => 'logo',
'image_return' => 'url', // Use 'id' to store the attachment ID instead.
]
Image fields automatically enqueue the WordPress media library when the settings are set up.
Example Code Editor Field
[
'type' => 'code-editor',
'title' => 'Custom CSS',
'id' => 'custom_css',
'name' => 'custom_css',
'code_type' => 'css',
'code_theme' => 'dracula',
'rows' => 10,
'cols' => 80,
'default' => '',
]
code_type accepts shorthand values like css, js, javascript, php, html, json, scss, and markdown, or a full MIME-style value like text/css or application/x-httpd-php.
If you set code_theme, the helper only passes the theme name to CodeMirror. It does not enqueue the theme stylesheet for you. You can get the matching CodeMirror 5 theme CSS file from https://github.com/codemirror/codemirror5/tree/master/theme, add it to your plugin or theme, and enqueue it yourself:
add_action( 'admin_enqueue_scripts', function() { wp_enqueue_style( 'my-plugin-codemirror-theme', plugins_url( 'assets/css/codemirror/dracula.css', __FILE__ ), [ 'wp-codemirror' ], false ); } );
Sanitization and Validation
sanitize_settings($option) is abstract and must be implemented in your child class. Use it to sanitize and validate all option values before they are saved to the database.
public function sanitize_settings( $option ) { $sanitized = []; if ( isset( $option['api_key'] ) ) { $sanitized['api_key'] = sanitize_text_field( $option['api_key'] ); } if ( isset( $option['logo'] ) ) { $sanitized['logo'] = esc_url_raw( $option['logo'] ); } $sanitized['enable_feature'] = ! empty( $option['enable_feature'] ) ? 1 : 0; return $sanitized; }
Upgrading to 2.0.0
Version 2.0.0 includes breaking changes:
sanitize_settings()is now abstract. Every child class must implement it.$settings_optionsand$settings_sectionsare nowprotected. Configure them inside your child class instead of reading or writing them from external code.
Composer constraints that only allow ^1.x will need to be updated before installing 2.0.0.