Introduction & Plugin Architecture
Welcome to Modern Plugin Development
WordPress plugins extend and modify WordPress functionality without touching core files. In this tutorial, you'll build a complete Task Manager plugin using modern object-oriented PHP patterns.
By the end, you'll have a fully-functional plugin that:
- Uses proper OOP architecture with namespaces
- Has its own admin interface with settings
- Stores data in a custom database table
- Exposes a REST API for AJAX operations
- Follows WordPress coding standards and security best practices
The Plugin Header
Every WordPress plugin starts with a header comment in the main PHP file:
<?php
/**
* Plugin Name: Task Manager
* Plugin URI: https://example.com/task-manager
* Description: A modern task management plugin built with OOP.
* Version: 1.0.0
* Requires at least: 6.0
* Requires PHP: 8.0
* Author: Your Name
* Author URI: https://example.com
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: task-manager
* Domain Path: /languages
*/Plugin Name is truly required, but including Version, Description, Author, and Text Domain is standard practice.
Modern Plugin File Structure
We'll use this organized structure for our Task Manager plugin:
task-manager/
โโโ task-manager.php # Main plugin file (bootstrap)
โโโ composer.json # Autoloading configuration
โโโ uninstall.php # Cleanup on uninstall
โโโ readme.txt # WordPress.org readme
โโโ assets/
โ โโโ css/
โ โ โโโ admin.css # Admin styles
โ โโโ js/
โ โโโ admin.js # Admin scripts
โโโ languages/
โ โโโ task-manager.pot # Translation template
โโโ src/ # PHP source files
โ โโโ Plugin.php # Main plugin class
โ โโโ Activator.php # Activation logic
โ โโโ Deactivator.php # Deactivation logic
โ โโโ Admin/
โ โ โโโ AdminMenu.php # Admin menu registration
โ โ โโโ Settings.php # Settings page
โ โ โโโ TasksPage.php # Tasks management page
โ โโโ Database/
โ โ โโโ TasksTable.php # Database operations
โ โโโ REST/
โ โ โโโ TasksController.php # REST API endpoints
โ โโโ Models/
โ โโโ Task.php # Task data model
โโโ vendor/ # Composer autoloader (gitignored)Why Object-Oriented PHP?
Traditional WordPress plugins often use procedural code with prefixed functions:
// โ Procedural approach - harder to maintain
function tm_create_task( $title ) { /* ... */ }
function tm_get_tasks() { /* ... */ }
function tm_delete_task( $id ) { /* ... */ }
function tm_admin_menu() { /* ... */ }
function tm_enqueue_scripts() { /* ... */ }OOP provides better organization, reusability, and testability:
// โ
OOP approach - clean and maintainable
namespace TaskManagerDatabase;
class TasksTable {
public function create( array $data ): int { /* ... */ }
public function find( int $id ): ?Task { /* ... */ }
public function delete( int $id ): bool { /* ... */ }
}Benefits of OOP in Plugins
- Encapsulation โ Related code grouped in classes
- Namespaces โ No function name collisions
- Autoloading โ No manual
requirestatements - Testability โ Classes can be unit tested
- Reusability โ Extend and compose classes
The Main Plugin File
Our bootstrap file will be minimal โ just constants and initialization:
<?php
/**
* Plugin Name: Task Manager
* ...header fields...
*/
// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Plugin constants
define( 'TM_VERSION', '1.0.0' );
define( 'TM_PLUGIN_FILE', __FILE__ );
define( 'TM_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'TM_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
// Composer autoloader
if ( file_exists( TM_PLUGIN_DIR . 'vendor/autoload.php' ) ) {
require_once TM_PLUGIN_DIR . 'vendor/autoload.php';
}
// Initialize plugin
function tm_init() {
return TaskManagerPlugin::get_instance();
}
add_action( 'plugins_loaded', 'tm_init' );
// Activation & Deactivation
register_activation_hook( __FILE__, [ TaskManagerActivator::class, 'activate' ] );
register_deactivation_hook( __FILE__, [ TaskManagerDeactivator::class, 'deactivate' ] );if ( ! defined( 'ABSPATH' ) ) exit; check to prevent direct file access.
What We'll Build: Task Manager
Throughout this tutorial, we'll build these features:
| Feature | Techniques |
|---|---|
| Admin dashboard | add_menu_page(), custom templates |
| Settings page | Settings API, options storage |
| Task CRUD | Custom database table, $wpdb |
| REST API | register_rest_route(), controllers |
| AJAX interface | wp_ajax_*, JavaScript fetch |
| Security | Nonces, capabilities, sanitization |
Setting Up Your Development Environment
Before we start coding, ensure you have:
- Local WordPress โ LocalWP, DDEV, or Docker
- Composer โ For autoloading (
composer init) - Code editor โ VS Code with PHP Intelephense
- Debug mode โ Enable
WP_DEBUGin wp-config.php
// wp-config.php - Development settings
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', true );
define( 'SCRIPT_DEBUG', true );Next Steps
In the next lesson, we'll set up Composer, configure PSR-4 autoloading, and create our main Plugin class using the singleton pattern.