A modern, developer-friendly WordPress options page builder with React UI and object-oriented architecture.
PathOfSettings is a comprehensive package for creating custom settings pages in WordPress applications. It provides a clean, object-oriented API for registering pages and fields, with a modern React-based admin interface that integrates seamlessly with WordPress core components.
- π Ultra-Simple API: One-line initialization, no configuration required
- β‘ Plug & Play: Built assets included, no build step needed
- π¨ Modern UI: React-powered interface using WordPress Gutenberg components
- ποΈ Clean Architecture: Object-oriented design with interfaces and services
- π Flexible Integration: Works in both plugins and themes via Composer
- π‘οΈ Type Safety: Full PHP 7.4+ type hints and comprehensive PHPDoc
- π REST API: Custom endpoints for secure settings management
- π¦ Extensible: Support for custom field types
- π i18n Ready: Full internationalization support
composer require whaze/path-of-settingsThat's it! Built assets are included in the package, no additional build step required.
- Download the latest release from GitHub
- Extract to your plugin or theme directory
- Include the autoloader in your code
<?php
// 1. Include Composer autoloader
require_once __DIR__ . '/vendor/autoload.php';
// 2. Initialize PathOfSettings (one line!)
\PathOfSettings\PathOfSettings::getInstance()->init();
// 3. Register your settings
add_action('pos_register_pages', function() {
// Create a settings page
pos_register_page('my-settings', [
'title' => __('My Settings', 'textdomain'),
'menu_title' => __('Settings', 'textdomain'),
]);
// Add fields
pos_add_field('my-settings', 'text', 'api_key', [
'label' => __('API Key', 'textdomain'),
'description' => __('Enter your API key', 'textdomain'),
'required' => true,
]);
pos_add_field('my-settings', 'select', 'mode', [
'label' => __('Operation Mode', 'textdomain'),
'options' => [
'live' => __('Live', 'textdomain'),
'test' => __('Test', 'textdomain'),
],
'default' => 'test',
]);
});That's it! π Your settings page is ready with a modern React interface.
<?php
/**
* Plugin Name: My Awesome Plugin
*/
// Include Composer autoloader
require_once __DIR__ . '/vendor/autoload.php';
// Initialize on plugin load
add_action('plugins_loaded', function() {
\PathOfSettings\PathOfSettings::getInstance()->init();
});
// Register plugin settings
add_action('pos_register_pages', function() {
pos_register_page('my-plugin-settings', [
'title' => __('My Plugin Settings', 'my-plugin'),
'capability' => 'manage_options',
]);
pos_add_field('my-plugin-settings', 'text', 'api_key', [
'label' => __('API Key', 'my-plugin'),
'required' => true,
]);
pos_add_field('my-plugin-settings', 'checkbox', 'enable_feature', [
'label' => __('Enable Advanced Feature', 'my-plugin'),
'default' => false,
]);
});
// Use settings in your plugin
function my_plugin_get_api_key() {
return pos_get_setting('my-plugin-settings', 'api_key', '');
}<?php
// In your theme's functions.php
require_once get_template_directory() . '/vendor/autoload.php';
// Initialize for theme
\PathOfSettings\PathOfSettings::getInstance()->init();
// Register theme options
add_action('pos_register_pages', function() {
pos_register_page('theme-options', [
'title' => __('Theme Options', 'my-theme'),
'capability' => 'edit_theme_options',
]);
pos_add_field('theme-options', 'text', 'primary_color', [
'label' => __('Primary Color', 'my-theme'),
'placeholder' => '#007cba',
]);
pos_add_field('theme-options', 'textarea', 'custom_css', [
'label' => __('Custom CSS', 'my-theme'),
'rows' => 8,
]);
});
// Use in your theme
function get_theme_primary_color() {
return pos_get_setting('theme-options', 'primary_color', '#007cba');
}Register a new settings page.
Parameters:
$id(string): Unique page identifier$args(array): Page configurationtitle(string): Page titlemenu_title(string): Menu title (optional, defaults to title)capability(string): Required capability (default:manage_options)
Returns: PageInterface object
Example:
pos_register_page('my-settings', [
'title' => 'My Settings Page',
'menu_title' => 'Settings',
'capability' => 'manage_options',
]);Add a field to a settings page.
Parameters:
$pageId(string): Target page ID$type(string): Field type (text,textarea,select,checkbox)$id(string): Unique field identifier$args(array): Field configurationlabel(string): Field labeldescription(string): Help text (optional)default(mixed): Default value (optional)required(bool): Whether field is required (optional)placeholder(string): Placeholder text (optional)options(array): Options for select fields (optional)
Returns: FieldInterface object
Retrieve a setting value.
Parameters:
$pageId(string): Page identifier$fieldId(string): Field identifier$default(mixed): Default value if not found
Returns: Mixed setting value
Example:
$api_key = pos_get_setting('my-settings', 'api_key', '');
$is_enabled = pos_get_setting('my-settings', 'enable_feature', false);Retrieve all settings for a page.
Parameters:
$pageId(string): Page identifier
Returns: Array of all page settings
pos_add_field('page-id', 'text', 'field-id', [
'label' => 'Text Input',
'description' => 'Enter some text',
'placeholder' => 'Type here...',
'required' => true,
]);pos_add_field('page-id', 'textarea', 'field-id', [
'label' => 'Long Text',
'description' => 'Enter longer content',
'rows' => 5,
'placeholder' => 'Enter your content here...',
]);pos_add_field('page-id', 'select', 'field-id', [
'label' => 'Choose Option',
'description' => 'Select an option from the dropdown',
'options' => [
'option1' => 'Option 1',
'option2' => 'Option 2',
'option3' => 'Option 3',
],
'default' => 'option1',
]);pos_add_field('page-id', 'checkbox', 'field-id', [
'label' => 'Enable Feature',
'description' => 'Check to enable this feature',
'default' => false,
]);Extend the package by creating custom field types:
use PathOfSettings\Core\Contracts\FieldInterface;
class CustomField implements FieldInterface {
// Implement required methods
public function getId(): string { /* ... */ }
public function getType(): string { return 'custom'; }
// ... other methods
}
// Register the field type
add_action('init', function() {
$registry = \PathOfSettings\Core\Registries\FieldsRegistry::getInstance();
$registry->register('custom', CustomField::class);
});For advanced use cases, you can pass configuration options:
\PathOfSettings\PathOfSettings::getInstance()->init([
'version' => '2.1.0', // Custom version
'path' => plugin_dir_path(__FILE__), // For custom textdomain loading
'url' => plugin_dir_url(__FILE__),
'file' => __FILE__,
]);pos_register_pages- Register your settings pagespos_after_save_settings- Fired after settings are saved
pos_before_save_settings- Filter settings before saving
add_filter('pos_before_save_settings', function($settings, $pageId) {
// Modify settings before saving
if ($pageId === 'my-settings') {
$settings['api_key'] = strtoupper($settings['api_key']);
}
return $settings;
}, 10, 2);
add_action('pos_after_save_settings', function($settings, $pageId) {
// Do something after settings are saved
if ($pageId === 'my-settings') {
// Clear cache, send notification, etc.
}
}, 10, 2);PathOfSettings automatically creates REST endpoints:
GET /wp-json/pos/v1/settings/{page-id}- Retrieve settingsPOST /wp-json/pos/v1/settings/{page-id}- Update settings
Example API usage:
// Get settings
fetch('/wp-json/pos/v1/settings/my-settings')
.then(response => response.json())
.then(settings => console.log(settings));
// Update settings
fetch('/wp-json/pos/v1/settings/my-settings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': wpApiSettings.nonce
},
body: JSON.stringify({
api_key: 'new-api-key',
enable_feature: true
})
});Complete working examples are available in the /examples directory:
examples/plugin-example.php- Full plugin implementationexamples/theme-example.php- Complete theme integration
<?php
/**
* Plugin Name: Simple Contact Form
*/
require_once __DIR__ . '/vendor/autoload.php';
// Initialize PathOfSettings
add_action('plugins_loaded', function() {
\PathOfSettings\PathOfSettings::getInstance()->init();
});
// Register contact form settings
add_action('pos_register_pages', function() {
pos_register_page('contact-form-settings', [
'title' => __('Contact Form Settings', 'simple-contact-form'),
'menu_title' => __('Contact Form', 'simple-contact-form'),
]);
// Email settings
pos_add_field('contact-form-settings', 'text', 'recipient_email', [
'label' => __('Recipient Email', 'simple-contact-form'),
'description' => __('Email address to receive form submissions', 'simple-contact-form'),
'required' => true,
'placeholder' => 'admin@example.com',
]);
pos_add_field('contact-form-settings', 'text', 'subject_prefix', [
'label' => __('Email Subject Prefix', 'simple-contact-form'),
'default' => '[Contact Form]',
'placeholder' => '[Contact Form]',
]);
// Form settings
pos_add_field('contact-form-settings', 'checkbox', 'require_phone', [
'label' => __('Require Phone Number', 'simple-contact-form'),
'description' => __('Make phone number field required', 'simple-contact-form'),
'default' => false,
]);
pos_add_field('contact-form-settings', 'select', 'form_style', [
'label' => __('Form Style', 'simple-contact-form'),
'options' => [
'default' => __('Default', 'simple-contact-form'),
'modern' => __('Modern', 'simple-contact-form'),
'minimal' => __('Minimal', 'simple-contact-form'),
],
'default' => 'default',
]);
});
// Use settings in your plugin
function scf_get_recipient_email() {
return pos_get_setting('contact-form-settings', 'recipient_email', get_admin_email());
}
function scf_is_phone_required() {
return pos_get_setting('contact-form-settings', 'require_phone', false);
}- PHP: 7.4 or higher
- WordPress: 5.8 or higher
- Browser: Modern browser with JavaScript enabled (for admin interface)
If the React interface doesn't appear:
- Check browser console for JavaScript errors
- Verify
build/directory exists in the package - Enable
WP_DEBUGto see detailed error messages
If you can't access settings pages:
- Verify user has required capability (
manage_optionsby default) - Check if pages are registered correctly
- Ensure
pos_register_pagesaction is firing
If Composer installation fails:
- Update Composer:
composer self-update - Clear cache:
composer clear-cache - Try without cache:
composer install --no-cache
# Clone repository
git clone https://github.com/whaze/path-of-settings.git
cd path-of-settings
# Install PHP dependencies
composer install
# Install Node.js dependencies
npm install
# Build assets for development
npm run start
# Build assets for production
npm run build# Check PHP code standards
composer run phpcs
# Fix PHP code standards
composer run phpcbf
# Check JavaScript standards
npm run lint:js
# Fix JavaScript standards
npm run lint:js:fix# Run JavaScript tests
npm run test:unit
# Format code
npm run format- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow WordPress coding standards
- Add PHPDoc for all public methods
- Include unit tests for new features
- Update documentation for API changes
- Test in both plugin and theme contexts
- Added: Auto-detection of package assets path
- Added: Simplified initialization API
- Added: Better error handling and debugging
- Improved: Documentation with more examples
- Fixed: Asset loading in theme contexts
- Initial release
- React-powered admin interface
- Support for text, textarea, select, and checkbox fields
- REST API endpoints
- Composer package support
This project is licensed under the GPL-2.0-or-later License. See the LICENSE file for details.
- Issues: GitHub Issues
- Documentation: GitHub Wiki
- Discussions: GitHub Discussions
Developed by Jerome Buquet (Whaze)
Built with β€οΈ for the WordPress community.
- WordPress Core Team for the excellent Gutenberg components
- The Composer team for making PHP package management awesome
- All contributors and users of this package
- π¨ Additional field types (color picker, media uploader, date picker)
- π Field groups and conditional logic
- π Import/export functionality
- π Multi-site network support
- π― Advanced validation rules
- π WordPress Customizer integration
- π± Better mobile responsive design
- β‘ Field lazy loading
- πΎ Advanced settings caching
- π¦ Asset optimization
- ποΈ Database optimization
Want to contribute to any of these features? Check out our contributing guide!