Skip to main content

Base Plugin Boilerplate

Modern WordPress plugin development starter template with PHP 8.2+, PSR-4 autoloading, and best practices.

Overview

Base Plugin Boilerplate is a comprehensive starter template for building WordPress plugins following modern PHP standards, WordPress coding conventions, and industry best practices. It provides a structured foundation with all boilerplate code, development tools, and architectural patterns needed to build production-ready plugins.

Current Version: 1.0.0
Requires: WordPress 6.4+, PHP 8.2+
License: GPL-2.0-or-later

Key Features

Modern PHP Standards

  • PHP 8.2+ Support — Strict types, type hints, union types
  • PSR-4 Autoloading — Composer-based class loading
  • Namespaced Code — Organized with PHP namespaces
  • Singleton Pattern — Proper plugin initialization
  • Type Safety — Full type declarations on all methods

WordPress Best Practices

  • WordPress Coding Standards — Follows WordPress.org guidelines
  • Security First — Nonce verification, capability checks, sanitization
  • Hooks & Filters — Proper action/filter usage
  • Internationalization — Translation-ready with text domains
  • Uninstall Handler — Clean removal of plugin data

Development Tools

  • Composer — PHP dependency management
  • Laravel Mix — JavaScript/CSS asset compilation
  • npm Scripts — Build automation
  • Auto-Updater — GitLab-based update checker
  • Code Organization — Modular class-based architecture

Pre-Built Components

  • Admin Settings Page — Framework for settings UI
  • Admin Class — Admin-specific functionality
  • Frontend Class — Public-facing features
  • System Class — Global plugin logic
  • Utils Class — Helper functions and utilities

Architecture Overview

Plugin Main File (init.php)

Plugin Class (Singleton)

├── Admin Class (Admin hooks)
├── Frontend Class (Public hooks)
├── System Class (Global hooks)
└── Settings Page Class

File Structure

base-plugin-boilerplate/
├── init.php # Plugin bootstrap
├── composer.json # PHP dependencies
├── package.json # Node dependencies
├── webpack.mix.js # Asset compilation
├── inc/ # PHP classes
│ ├── class-plugin.php # Main plugin singleton
│ ├── class-admin.php # Admin functionality
│ ├── class-frontend.php # Public functionality
│ ├── class-system.php # Global logic
│ ├── class-utils.php # Helper functions
│ └── settings/
│ └── class-page.php # Settings page
├── lib/ # Third-party libraries
│ └── plugin-update-checker/ # Auto-update system
├── src/ # Source assets
│ ├── js/ # JavaScript files
│ │ ├── admin.js # Admin scripts
│ │ └── frontend.js # Frontend scripts
│ └── scss/ # Sass stylesheets
│ ├── admin.scss # Admin styles
│ └── frontend.scss # Frontend styles
├── dist/ # Compiled assets
│ ├── css/
│ │ ├── admin.css
│ │ └── frontend.css
│ └── js/
│ ├── admin.js
│ └── frontend.js
├── languages/ # Translation files
│ └── your-plugin-key.pot
└── uninstall.php # Cleanup on uninstall

Quick Start Guide

1. Clone and Rename

git clone [repository-url] my-plugin-name
cd my-plugin-name

2. Search and Replace

Perform these case-sensitive replacements across all files:

FindReplacePurpose
Suma\BoilerplateYourCompany\YourPluginNamespace
SUMA_PLUGIN_NAMEYOUR_PLUGIN_NAMEPlugin name constant
SUMA_PLUGIN_KEYyour-plugin-keyPlugin slug
suma-plugin-keyyour-plugin-keyText domain
SUMA_PLUGIN_VERSIONYOUR_PLUGIN_VERSIONVersion constant

3. Update Plugin Header

Edit init.php:

/**
* Plugin Name: Your Plugin Name
* Plugin URI: https://yourwebsite.com
* Description: Your plugin description
* Version: 1.0.0
* Author: Your Name
* Author URI: https://yourwebsite.com
* Text Domain: your-plugin-key
*/

4. Install Dependencies

composer install --no-dev --optimize-autoloader
npm install

5. Build Assets

npm run prod

6. Activate Plugin

Upload to WordPress and activate via Plugins page.

Development Workflow

Asset Development

npm run dev        # Development build (unminified)
npm run watch # Watch for changes (live reload)
npm run prod # Production build (minified)

PHP Development

  • Classes in inc/ namespace YourCompany\YourPlugin
  • Follow WordPress PHP Coding Standards
  • Use type hints on all methods
  • Document with PHPDoc blocks

Testing

composer test      # Run PHP unit tests
npm run test # Run JavaScript tests

Core Classes

Plugin Class

File: inc/class-plugin.php

Singleton pattern main plugin class:

namespace YourCompany\YourPlugin;

class Plugin {
private static $instance = null;

public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}

public function run() {
$this->load_dependencies();
$this->define_admin_hooks();
$this->define_frontend_hooks();
$this->define_system_hooks();
}
}

Admin Class

File: inc/class-admin.php

Handles admin-specific functionality:

  • Enqueue admin assets
  • Register meta boxes
  • Process admin forms
  • Add admin notices

Frontend Class

File: inc/class-frontend.php

Handles public-facing functionality:

  • Enqueue frontend assets
  • Register shortcodes
  • Template overrides
  • AJAX endpoints

System Class

File: inc/class-system.php

Global plugin logic:

  • Custom post types
  • Custom taxonomies
  • REST API endpoints
  • Cron jobs

Settings Page Class

File: inc/settings/class-page.php

Settings API implementation:

  • Register settings
  • Render settings page
  • Sanitize user input
  • Store configuration

Security Features

Nonce Verification

if (!wp_verify_nonce($_POST['nonce'], 'action_name')) {
wp_die('Security check failed');
}

Capability Checks

if (!current_user_can('manage_options')) {
return;
}

Input Sanitization

$value = sanitize_text_field($_POST['field']);
$email = sanitize_email($_POST['email']);
$url = esc_url_raw($_POST['url']);

Output Escaping

echo esc_html($user_data);
echo esc_attr($attribute);
echo esc_url($link);

Auto-Update System

Built-in GitLab update checker:

$updater = new PluginUpdateChecker(
'https://gitlab.com/user/repo',
__FILE__,
'plugin-slug'
);

$updater->setBranch('main');
$updater->setAuthentication('your-access-token');

Localization Support

Translation-ready with text domain:

__('String to translate', 'your-plugin-key');
_e('Echo translated string', 'your-plugin-key');
_n('Singular', 'Plural', $count, 'your-plugin-key');

Generate POT file:

wp i18n make-pot . languages/your-plugin-key.pot

Customization Points

Add Custom Settings

Edit inc/settings/class-page.php:

register_setting('option_group', 'option_name');
add_settings_field('field_id', 'Label', [$this, 'callback'], 'page_slug', 'section');

Add Custom Post Type

Edit inc/class-system.php:

register_post_type('custom_type', [
'label' => 'Custom Type',
'public' => true,
'supports' => ['title', 'editor']
]);

Add Admin Menu Page

Edit inc/class-admin.php:

add_menu_page('Page Title', 'Menu Label', 'manage_options', 'page-slug', [$this, 'render_page']);

Best Practices Included

  • ✅ Singleton pattern for plugin initialization
  • ✅ PSR-4 autoloading with Composer
  • ✅ Proper hook and filter usage
  • ✅ Security with nonces and capability checks
  • ✅ Input sanitization and output escaping
  • ✅ Separation of concerns (admin/frontend/system)
  • ✅ Asset enqueuing with wp_enqueue_*
  • ✅ Translation support with text domains
  • ✅ Uninstall cleanup handler
  • ✅ Auto-update from GitLab
  • ✅ Modern asset compilation with Mix

Production Checklist

Before deploying:

  • Update version numbers
  • Build production assets (npm run prod)
  • Run Composer install with --no-dev
  • Test activation/deactivation
  • Test uninstall cleanup
  • Verify translations load
  • Check security implementations
  • Review error logging
  • Test auto-updater
  • Document configuration