Author: haoxiaogen1290akira@gmail.com

  • Building Scalable WordPress Plugins from Scratch

    Most WordPress plugin tutorials show you how to get something working in 50 lines.
    That’s fine for learning, but when you’re shipping to real clients — with real edge cases,
    real update cycles, and real support tickets — you need a different approach entirely.

    This is what I’ve learned after building and maintaining several production plugins
    for Japanese legal service firms and marketing teams.

    Project Structure That Scales

    The single biggest mistake I see in plugin codebases is treating functions.php
    like a junk drawer. Everything goes in, nothing comes out cleanly. Instead, think of your
    plugin as a small application with real separation of concerns.

    plaintext

    my-plugin/
                      ├── my-plugin.php          # Bootstrap only
                      ├── includes/
                      │   ├── class-core.php     # Main plugin class
                      │   ├── class-admin.php    # WP Admin screens
                      │   ├── class-api.php      # REST endpoints
                      │   └── class-db.php       # DB abstraction
                      ├── assets/
                      │   ├── js/
                      │   └── css/
                      └── templates/             # Frontend views

    The main plugin file should do almost nothing — just load the autoloader and
    instantiate the core class. No business logic, no hooks, no output.

    Hook Architecture

    WordPress is built on hooks. But managing them naively leads to impossible-to-debug
    interactions where you can’t tell what’s registered or when. Use a pattern I call
    deferred hook registration: collect all hooks in a manifest, register
    them in a single pass at boot time.

    php

    class Plugin_Core {
    
                    private $hooks = [];
    
                    public function register_hook($type, $tag, $callback, $priority = 10) {
                      $this->hooks[] = compact('type', 'tag', 'callback', 'priority');
                    }
    
                    public function run() {
                      foreach ($this->hooks as $hook) {
                        call_user_func(
                          'add_' . $hook['type'],
                          $hook['tag'],
                          $hook['callback'],
                          $hook['priority']
                        );
                      }
                    }
                  }

    The goal isn’t to write clever code. It’s to write code that your future self —
    or a contractor — can understand at 11pm when something breaks in production.

    Database Layer

    Never write raw SQL scattered through your plugin. Always abstract it. Even if you’re
    only doing simple queries today, you’ll thank yourself when you need to swap table
    prefixes, add caching, or migrate to a custom post type.

    php

    class Plugin_DB {
    
                    private static $table;
    
                    public static function init() {
                      global $wpdb;
                      self::$table = $wpdb->prefix . 'my_plugin_data';
                    }
    
                    public static function get_entries($limit = 20) {
                      global $wpdb;
                      return $wpdb->get_results(
                        $wpdb->prepare(
                          "SELECT * FROM %i ORDER BY created_at DESC LIMIT %d",
                          self::$table, $limit
                        )
                      );
                    }
                  }

    Security Fundamentals

    Every form submission needs a nonce. Every AJAX handler needs capability checks.
    Every output needs escaping. These are not optional — they’re the minimum bar
    for a plugin that won’t embarrass you.

    One pattern I enforce in every plugin: validate on the way in,
    escape on the way out
    . Never trust user data anywhere in the stack,
    and never output anything without an appropriate escape function.

    Nonce Verification Pattern

    php

    function handle_form_submission() {
                    // 1. Verify nonce
                    if ( ! check_ajax_referer( 'my_plugin_action', 'nonce', false ) ) {
                      wp_send_json_error( ['msg' => 'Invalid nonce'], 403 );
                    }
    
                    // 2. Check capability
                    if ( ! current_user_can( 'manage_options' ) ) {
                      wp_send_json_error( ['msg' => 'Unauthorized'], 401 );
                    }
    
                    // 3. Sanitize input
                    $value = sanitize_text_field( $_POST['value'] ?? '' );
    
                    // 4. Do the work...
                  }

    Takeaways

    Building production WordPress plugins is mostly about discipline, not ingenuity.
    The patterns that work are boring on purpose: structured files, explicit hooks,
    abstracted data access, security by default.

    The reward for that boring foundation is a codebase you can actually maintain —
    and clients who don’t call you at midnight.

    Most WordPress plugin tutorials show you how to get something working in 50 lines. That’s fine for learning, but when you’re shipping to real clients — with real edge cases, real update cycles, and real support tickets — you need a different approach entirely. This is what I’ve learned after building and maintaining several production…

  • Hello world!

    Welcome to WordPress. This is your first post. Edit or delete it, then start writing!

数字化顾问(beta)