WordPress Plugin Development Basics 2026
Published April 21, 2026
WordPress Plugin Development Basics
Plugins extend WordPress with custom functionality. Whether you're solving a specific problem for your own site or building something to distribute, understanding plugin development fundamentals helps you write maintainable, secure, and compatible code.
Plugin File Structure
Every plugin lives in its own directory under wp-content/plugins/. The main plugin file must contain a header comment:
/*
Plugin Name: My Plugin
Plugin URI: https://example.com
Description: What this plugin does.
Version: 1.0.0
Author: Your Name
License: GPL-2.0-or-later
*/
WordPress reads this header to display the plugin in the admin Plugins list.
Activation, Deactivation, and Uninstall Hooks
register_activation_hook(): Runs when the plugin is activated. Use for creating database tables, setting default options.register_deactivation_hook(): Runs on deactivation. Clean up temporary data, unschedule cron jobs.register_uninstall_hook()oruninstall.php: Runs when the plugin is deleted. Remove database tables and options completely.
Adding Settings Pages
Use the Settings API to add options pages: add_options_page() for a settings page under Settings, register_setting() to register each option, and add_settings_section() / add_settings_field() to build the form. The Settings API handles nonce verification, sanitization callbacks, and error messaging automatically.
Security Fundamentals
- Nonces: Verify that form submissions come from your forms with
wp_nonce_field()andwp_verify_nonce() - Capability checks: Always verify
current_user_can()before performing admin actions - Sanitize inputs: Use
sanitize_text_field(),absint(),esc_url_raw()for all user input - Escape outputs: Use
esc_html(),esc_attr(),esc_url(),wp_kses()for all output - Direct access prevention: Add
if ( ! defined( 'ABSPATH' ) ) exit;at the top of every PHP file
Database Operations
Use $wpdb for database queries. Always use prepared statements: $wpdb->prepare( 'SELECT * FROM table WHERE id = %d', $id ). This prevents SQL injection. For simple options, use the Options API (get_option(), update_option()) which handles serialization automatically.
Plugin Development Best Practices
- Prefix all functions, classes, and global variables with a unique prefix
- Use object-oriented structure for plugins longer than a few hundred lines
- Load plugin textdomain for internationalization
- Test with
WP_DEBUGenabled — fix all notices and warnings - Follow WordPress Coding Standards (PHPCS with WordPress ruleset)