ブログ

WordPressフックアーキテクチャ:アクションとフィルターの違いを解説

あらゆる優れたプラグインの基盤。PAGEnza AIがどのようにフックとフィルターを使用して、保守可能でスケーラブルなコードを作成するかを学びましょう。

すべてのWordPressプラグインは、次の2つのうちのいずれかを行います。特定の瞬間にコードを実行する(アクション)、または使用前に値を変更する(フィルター)。それだけです。WordPressプラグインエコシステム全体がこの区別の上に構築されています。

違いを理解すること、そしていつどちらを使用するかを知ることは、うまく機能するプラグインと問題を引き起こすプラグインを分けるものです。

アクション:特定の時点で何かを実行する

アクションフックは、WordPress(または他のプラグイン)が特定の瞬間に送信する信号です。その信号に関数をアタッチすると、信号が発火したときにその関数が実行されます。

add_action( 'wp_enqueue_scripts', 'my_plugin_load_assets' );

function my_plugin_load_assets() {
    wp_enqueue_style( 'my-plugin', plugin_dir_url( __FILE__ ) . 'style.css' );
    wp_enqueue_script( 'my-plugin', plugin_dir_url( __FILE__ ) . 'script.js', ['jquery'], '1.0', true );
}

wp_enqueue_scriptsは、WordPressがフロントエンドのアセットをロードする準備をする際に発火します。これにフックすることは、CSSとJSをロードする正しい方法です。テンプレートに直接<script>タグをドロップするのではなく。

常に使用する一般的なアクションフック:

  • init — 早期に実行され、カスタム投稿タイプやタクソノミーの登録に適しています
  • wp_enqueue_scripts — フロントエンドアセットをロードします
  • admin_enqueue_scripts — 管理画面アセットをロードします
  • save_post — 投稿が保存されたときに実行され、カスタムフィールドの処理に適しています
  • wp_ajax_{action} — 認証済みユーザーからのAJAXリクエストを処理します
  • wp_ajax_nopriv_{action} — ログインしていないユーザーからのAJAXを処理します

フィルター:使用前に値を変更する

フィルターフックは、値を提供し、それを変更できるようにし、変更されたバージョンを返すことを期待します。WordPressはその後、元の値の代わりに変更された値を使用します。

add_filter( 'the_content', 'my_plugin_append_cta' );

function my_plugin_append_cta( $content ) {
    if ( ! is_single() ) {
        return $content;
    }
    $cta = '<div class="post-cta">PAGEnzaをお試しください。 <a href="#">無料ではじめる →</a></div>';
    return $content . $cta;
}

重要なルール:フィルターからは常に何かを返してくださいreturnを忘れると、値はnullになり、それを使用していたものを壊してしまいます。

一般的なフィルターフック:

  • the_content — 表示前の投稿コンテンツ
  • the_title — 投稿タイトル
  • wp_nav_menu_items — ナビゲーションメニューのHTML
  • upload_mimes — 許可されるファイルアップロードタイプ
  • plugin_action_links_{plugin-file} — プラグインリストページに表示されるリンク

PAGEnza AIはフックをどのように使用するか

プラグインビルダーがプラグインを生成する際、コンストラクタ内のフックにアタッチされたメソッドを持つクラスを中心にコードを構造化します。このパターンは、グローバル関数名の衝突を回避し、コードを整理された状態に保ちます。

class My_Plugin {
    public function __construct() {
        add_action( 'init', [ $this, 'register_post_type' ] );
        add_action( 'wp_enqueue_scripts', [ $this, 'load_assets' ] );
        add_filter( 'the_content', [ $this, 'append_content' ] );
    }

    public function register_post_type() { /* ... */ }
    public function load_assets() { /* ... */ }
    public function append_content( $content ) {
        // always return
        return $content;
    }
}

new My_Plugin();

セキュリティスキャンは、AJAXハンドラが何かを実行する前に、ノンスチェックと権限チェックの両方を含んでいることを特にチェックします。

add_action( 'wp_ajax_my_action', [ $this, 'handle_ajax' ] );

public function handle_ajax() {
    // Security: verify nonce
    check_ajax_referer( 'my_nonce_action', 'nonce' );

    // Security: verify permissions
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Insufficient permissions', 403 );
    }

    // Now safe to process
    $data = sanitize_text_field( $_POST['data'] ?? '' );
    wp_send_json_success( [ 'result' => $data ] );
}

これらのいずれかが欠落していると、セキュリティ問題としてフラグが立てられ、プラグインのリリースがブロックされます。

優先度とフックキュー

複数の関数が同じフックにアタッチされている場合、それらは優先度の順に実行されます(数値が小さいほど先に実行されます)。デフォルトの優先度は10です。

add_action( 'init', 'runs_first', 5 );
add_action( 'init', 'runs_second', 10 );   // default
add_action( 'init', 'runs_last', 20 );

これは、プラグインが他のプラグインのコードの前または後に実行する必要がある場合に重要です。他のプラグインも変更するものを変更している場合、優先度が勝者を制御します。

一般的なパターン:テーマのフィルターをオーバーライドする場合は、優先度20以上を使用して、テーマのコードの後に実行されるようにします。

フックの削除

他の人が追加したフック(テーマやプラグインのフックを含む)を削除できます。

remove_action( 'wp_head', 'wp_generator' );  // removes WP version from <head>
remove_filter( 'the_content', 'wpautop' );   // removes automatic paragraph wrapping

注意点:元のadd_action/add_filterが実行された後にremove_action/remove_filterを呼び出した場合にのみ、フックを削除できます。これは通常、削除をより遅いアクションにフックすることを意味します。