WordPress Plugin Development

Turn a working WordPress plugin into a secure, tested, production-quality product.

  • Intermediate
  • 25 lessons
  • 10 hours

Start the course

Most WordPress plugins start as a single file that works on one site. Production plugins need more: admin screens that follow WordPress conventions, settings that save securely, data that survives upgrades, background work that does not time out, and a release process that does not break live sites. This course teaches those skills.

You continue the events plugin from the WordPress Development Complete Course, with its myplugin_event post type and bookings table, and grow it into a production-quality plugin: a settings screen, a versioned custom table, admin columns and meta boxes, background jobs with Action Scheduler, blocks for the editor, automated tests, coding standards checks and a release process for WordPress.org or your own update server.

The first half keeps the procedural style you already know. From the architecture lesson onwards, the plugin moves to namespaced classes loaded by Composer, so you see why and when that structure pays off.

Keep the plugin in a Git repository from the first lesson and commit after each one. By the end you will have a complete reference plugin, and a history that shows how each piece was added.

Curriculum

  1. 1 Plugin foundations

    Create a plugin properly, organise its files, prefix everything, and run setup and clean-up on activation, deactivation and uninstall.

    1. Your first WordPress plugin 9 min
    2. Plugin structure and best practices 9 min
    3. Activation, deactivation and uninstall 9 min
  2. 2 Admin screens, settings and output

    Add admin menus and pages with the right capabilities, build a settings screen with the Settings API, and output content with shortcodes.

    1. Admin menus and pages 9 min
    2. The Settings API 10 min
    3. Shortcodes 8 min
  3. 3 Data and the admin interface

    Version and upgrade a custom table, show notices without nagging, handle AJAX requests securely and build meta boxes without a library.

    1. Custom database tables 10 min
    2. Admin notices and admin UI conventions 9 min
    3. AJAX in WordPress plugins 9 min
    4. Meta boxes and custom fields without a library 8 min
  4. 4 Jobs, security and integration

    Run background jobs with Action Scheduler, review a plugin for security, extend admin lists and the dashboard, ship blocks and declare plugin dependencies.

    1. Background jobs with Action Scheduler 10 min
    2. Plugin security checklist 8 min
    3. Admin list table columns and dashboard widgets 11 min
    4. Integrating plugins with the block editor 12 min
    5. Plugin dependencies with Requires Plugins 8 min
  5. 5 Professional plugin engineering

    Move to a namespaced, class-based architecture with Composer autoloading, then add automated tests, coding standards checks and safe data migrations.

    1. Object-oriented plugin architecture 15 min
    2. Composer and autoloading in plugins 9 min
    3. Automated tests for plugins 9 min
    4. Coding standards with PHPCS and WPCS 8 min
    5. Data migrations and plugin updates 13 min
  6. 6 Shipping and scaling

    Support Multisite, add privacy export and erasure, deliver updates outside WordPress.org, publish on the plugin directory and keep the plugin fast on large sites.

    1. Multisite-compatible plugins 11 min
    2. Privacy tools: personal data export and erasure 11 min
    3. Licensing and updates for premium plugins 10 min
    4. Publishing on the WordPress.org plugin directory 10 min
    5. Plugin performance at scale 10 min

Test yourself: WordPress Plugin Development: final quiz

12 questions. Pass mark 70%.

  1. Question 1 of 12 A user deletes your plugin from the Plugins screen and has opted in to removing its data. Where should the code that drops the bookings table run?
  2. Question 2 of 12 Your settings page form posts to options.php. Which call prints the hidden fields that tell WordPress which settings group is being saved, including the nonce?
  3. Question 3 of 12 Editors report that this shortcode’s output appears at the top of the post instead of where they placed it. Why?
    PHP
    add_shortcode( 'myplugin_price', 'myplugin_price_shortcode' );
    
    function myplugin_price_shortcode( $atts ) {
    	echo '<span class="price">£20</span>';
    }
  4. Question 4 of 12 Version 1.2 of your plugin changes the bookings table. Which change will dbDelta() not make for you?
  5. Question 5 of 12 Any logged-in subscriber can use this AJAX handler to confirm bookings. What is missing?
    PHP
    add_action( 'wp_ajax_myplugin_confirm', 'myplugin_ajax_confirm' );
    
    function myplugin_ajax_confirm() {
    	check_ajax_referer( 'myplugin_confirm', 'nonce' );
    
    	$id = absint( $_POST['booking_id'] ?? 0 );
    	myplugin_set_booking_status( $id, 'confirmed' );
    
    	wp_send_json_success();
    }
  6. Question 6 of 12 You need to send reminder emails for 20,000 bookings. Which two are real advantages of queuing the work with Action Scheduler rather than one large WP-Cron callback?

    Select all that apply.

  7. Question 7 of 12 Your plugin hosts its own updates. Which filter lets it add its newer version to the data WordPress uses to show “update available”?
  8. Question 8 of 12 Your plugin ships a dynamic block whose block.json declares a render file. Where does its front-end HTML come from?
  9. Question 9 of 12 What does the header line Requires Plugins: woocommerce do in current versions of WordPress?
  10. Question 10 of 12 Two plugins on a site bundle different versions of the same Composer library under the same namespace. What usually happens?
  11. Question 11 of 12 Version 2.0 of your plugin must convert stored data. Users update by uploading the new version or through automatic updates. Where should the upgrade routine be triggered?
  12. Question 12 of 12 A plugin saves a 3 MB activity log with update_option( 'myplugin_log', $log ), and the option ends up autoloaded. What is the main effect?