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
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
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.