How to leave legacy technologies behind and build modern, scalable WordPress plugins
A comprehensive WordPress plugin development starter kit featuring modern PHP 8+ architecture, advanced utility classes, and best practices for building professional-grade plugins.
Note: This is a fork and enhancement of the excellent starter-plugin by Viktor Szépe. All credit for the original concept and foundation goes to the original author.
- PHP 8.0+ with strict types - Modern PHP features and type safety
- PSR-4 autoloading - Automated class loading with namespace support
- Immutable configuration - Clean, centralized plugin configuration
- Requirements checking - Automated environment validation
- Clean separation of concerns - Well-organized, maintainable code structure
- Caching system - Built-in request caching with WordPress transients
- Request counting - Track API usage with automatic reset
- Error handling - Comprehensive error management
- Endpoint management - Clean configuration-driven API calls
- Response validation - Automatic response processing and validation
- WordPress filesystem integration - Secure file operations
- Media library support - Upload and manage media files
- File validation - Type checking and security validation
- Upload directory management - Plugin-specific directory creation
- File metadata handling - Complete file information management
- Development mode detection - Smart debugging based on WP_DEBUG
- Console logging - Browser console integration
- Variable inspection - Enhanced print_r and var_dump
- Performance timing - Built-in performance monitoring
- Breakpoint system - Development debugging tools
- Admin notices - WordPress admin notification integration
- Page targeting - Show notifications on specific pages
- Auto-expiration - Time-based notification cleanup
- Multiple types - Success, error, warning, and info notifications
- Dismissible notices - User-controlled notification dismissal
- Admin pages - Menu and submenu page creation
- Frontend routing - Custom frontend page handling
- Template system - Flexible template loading
- Capability checking - Automatic permission validation
- Dashboard widgets - Custom dashboard widget support
- Route registration - Clean REST endpoint definition
- Middleware support - Request processing pipeline
- Validation system - Automatic parameter validation
- Sanitization - Built-in data sanitization
- Error handling - Standardized error responses
- WordPress Settings API - Full integration with WP settings
- Field rendering - Automatic form field generation
- Validation & sanitization - Built-in data validation
- Import/export - Settings backup and restore
- Group organization - Logical settings organization
- Cache management - Performance-optimized settings access
- PSR-4 compliance - Standard autoloading implementation
- Multiple namespaces - Support for complex plugin structures
- Class mapping - Direct class-to-file mapping
- Performance optimized - Efficient class loading with caching
- Development tools - Class discovery and mapping generation
The starter includes a complete example plugin that demonstrates all utilities:
- Automated monitoring - Scheduled health checks
- Multiple check types - Database, filesystem, memory, connectivity
- Admin dashboard - Comprehensive health status overview
- REST API - External monitoring integration
- Historical data - Track health metrics over time
- Email notifications - Alert system for critical issues
- Export functionality - Data export in JSON/CSV formats
- Performance tracking - Response time monitoring
APIHelper Implementation:
class HealthChecker extends APIHelper
{
const ENDPOINTS = [
'self_ping' => [
'route' => '/wp-json/site-health-monitor/v1/health',
'method' => 'GET',
'cache' => 300,
],
'external_check' => [
'route' => '/status/{{status_code}}',
'method' => 'GET',
'cache' => false,
],
];
}Settings Configuration:
Settings::init([
'monitoring_enabled' => [
'type' => 'checkbox',
'label' => __('Enable Monitoring'),
'default' => true,
'group' => 'general',
],
'check_interval' => [
'type' => 'select',
'choices' => [
'hourly' => __('Hourly'),
'daily' => __('Daily'),
],
],
]);REST API Endpoints:
RestRoute::get('/health', [HealthAPI::class, 'get_health_status']);
RestRoute::post('/check', [HealthAPI::class, 'trigger_check']);
RestRoute::get('/history', [HealthAPI::class, 'get_history']);Page Registration:
Page::add_menu_page('site-health-monitor', [
'page_title' => __('Site Health Monitor'),
'menu_title' => __('Health Monitor'),
'callback' => [MonitoringDashboard::class, 'render'],
'icon' => 'dashicons-heart',
]);- PHP 8.0 or higher
- WordPress 6.0 or higher
- Composer (for development)
- Clone the repository:
git clone https://github.com/codad5/starter-plugin.git my-plugin
cd my-plugin- Install dependencies:
composer install- Customize the plugin:
- Rename files and folders
- Update namespace in all files
- Modify the main plugin file header
- Configure your specific functionality
- Initialize utilities:
// In your main plugin file
use Company\WordPress\PluginName\Utils\{
Autoloader, Settings, Page, RestRoute, Notification, Debugger
};
// Initialize components
Autoloader::init();
Settings::init($your_settings);
Page::init();
RestRoute::init();
Notification::init();
Debugger::init();plugin-name/
├── src/
│ ├── Config.php # Configuration container
│ ├── Requirements.php # Environment validation
│ ├── Utils/
│ │ ├── APIHelper.php # HTTP requests & caching
│ │ ├── Autoloader.php # PSR-4 autoloading
│ │ ├── Debugger.php # Development debugging
│ │ ├── Notification.php # Admin notifications
│ │ ├── Page.php # Page management
│ │ ├── RestRoute.php # REST API framework
│ │ └── Settings.php # Settings management
│ └── Helpers/
│ └── Filesystem.php # File operations
├── assets/
│ ├── css/
│ └── js/
├── templates/ # Template files
├── languages/ # Translation files
├── vendor/ # Composer dependencies
├── plugin-name.php # Main plugin file
└── composer.json
Create API integrations with caching and error handling:
class MyAPIHelper extends APIHelper
{
protected static string $name = 'MyAPI';
const HOST = 'https://api.example.com';
const ENDPOINTS = [
'get_data' => [
'route' => '/data/{{id}}',
'method' => 'GET',
'cache' => 3600,
'params' => [
'api_key' => function() { return Settings::get('api_key'); }
]
]
];
}
// Usage
$data = MyAPIHelper::make_request('get_data', [], ['id' => '123']);Define and manage plugin settings:
Settings::add_settings([
'api_key' => [
'type' => 'password',
'label' => __('API Key'),
'validate_callback' => 'validate_api_key',
'group' => 'api'
],
'cache_duration' => [
'type' => 'number',
'default' => 3600,
'min' => 300,
'max' => 86400
]
]);
// Get settings
$api_key = Settings::get('api_key');
$cache_time = Settings::get('cache_duration', 3600);Create admin and frontend pages:
// Admin page
Page::add_menu_page('my-plugin', [
'page_title' => __('My Plugin'),
'menu_title' => __('My Plugin'),
'callback' => [MyAdminPage::class, 'render']
]);
// Frontend page
Page::add_frontend_page('my-page', [
'title' => __('My Custom Page'),
'template' => 'my-page-template.php',
'public' => true
]);Build REST endpoints with validation:
RestRoute::init('my-plugin');
RestRoute::get('/data', function($request) {
return RestRoute::success_response(['data' => 'example']);
});
RestRoute::post('/data', function($request) {
$value = $request->get_param('value');
// Process data
return RestRoute::success_response(['saved' => $value]);
}, [
'args' => [
'value' => [
'required' => true,
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field'
]
]
]);Use development debugging features:
// Console logging
Debugger::info('Process started', $data);
Debugger::warn('Performance issue detected');
Debugger::error('Critical error occurred');
// Variable inspection
Debugger::print_r($complex_data);
Debugger::var_dump($object);
// Performance timing
$start = Debugger::timer('My Operation');
// ... do work ...
Debugger::timer('My Operation', $start);
// Breakpoints (development only)
Debugger::breakpoint('Debug checkpoint', ['context' => $data]);Display admin notices:
// Success notification
Notification::success('Operation completed successfully');
// Error on specific page
Notification::error('Something went wrong', 'plugin');
// Warning with custom expiration
Notification::warning('Performance issue detected', 'all', 600);
// Info notice
Notification::info('New feature available');Always declare strict types at the top of your PHP files:
declare(strict_types=1);Organize classes in proper namespace hierarchy and let the autoloader handle includes:
namespace Company\WordPress\PluginName\Admin\Pages;
class SettingsPage {
// Class implementation
}Initialize utilities with proper configuration:
Config::init([
'slug' => 'my-plugin',
'name' => 'My Plugin',
'version' => '1.0.0',
// ... other config
]);Use try-catch blocks and proper error reporting:
try {
$result = APIHelper::make_request('endpoint');
} catch (\Exception $e) {
Debugger::error('API request failed: ' . $e->getMessage());
Notification::error('Operation failed. Please try again.');
}Always validate and sanitize user input:
Settings::add_setting('email', [
'type' => 'email',
'sanitize_callback' => 'sanitize_email',
'validate_callback' => 'is_email'
]);- Nonce verification - All forms and AJAX requests protected
- Capability checking - Proper permission validation
- Input sanitization - Built-in data cleaning
- File validation - Secure file upload handling
- SQL injection prevention - Prepared statements usage
- XSS protection - Output escaping
- Intelligent caching - Multiple caching layers
- Lazy loading - Components loaded when needed
- Database optimization - Efficient queries and indexing
- Asset minification - Optimized CSS/JS delivery
- Memory management - Efficient resource usage
The starter includes testing foundations:
- PHPUnit configuration
- WordPress testing framework integration
- Mock objects for WordPress functions
- Automated testing examples
- ❌ Global constants (use Config container)
- ❌ Global functions (use namespaced classes)
- ❌ Direct file includes (use autoloader)
- ❌ Immediate execution (use action hooks)
- ❌ Mixed HTML/PHP logic (use templates)
- ❌ Hardcoded values (use settings)
- ❌ Direct database queries (use WordPress APIs)
- Fork the repository at https://github.com/codad5/starter-plugin
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
GPL-2.0-or-later - see LICENSE file for details.
- Viktor Szépe - @szepeviktor - Original creator of the starter-plugin
- Codad5 - @codad5 - Enhanced version with advanced utilities
- WordPress Plugin Boilerplate community
- Contributors and testers
Please consider supporting the original creator:
Support this project: ⭐ Star the repository at https://github.com/codad5/starter-plugin if you find it helpful!
Also support the original work: ⭐ Star the original repository at https://github.com/szepeviktor/starter-plugin