2026年5月20日

2026年5月20日

WordPressプラグインでウィジェットを作成する方法

はじめに

WordPressのカスタムウィジェットは WP_Widget クラスを継承して作成します。WordPress 5.8以降はブロックウィジェットエディターに移行しましたが、WP_Widget は引き続き動作します。新規開発ではブロックとして実装することも推奨されます。

症状・原因

  • サイドバーやフッターにカスタムコンテンツを表示したい
  • ウィジェット管理画面で設定できるオプション付きウィジェットを作りたい
  • 既存テーマのウィジェットエリアにプラグインからコンテンツを追加したい
  • ウィジェットをWP-CLIで確認・管理したい

解決手順

ステップ1:WP_Widgetクラスでウィジェットを作成する

// プラグインのメインファイル
class Myplugin_Recent_Posts_Widget extends WP_Widget {

    public function __construct() {
        parent::__construct(
            'myplugin_recent_posts',           // ウィジェットID
            'MY: 最近の投稿',                   // 管理画面に表示する名前
            [
                'description' => '最近の投稿をカスタム表示するウィジェット',
                'classname'   => 'myplugin-recent-posts',
            ]
        );
    }

    // フロントエンドの出力
    public function widget(array $args, array $instance): void {
        $title = apply_filters(
            'widget_title',
            $instance['title'] ?? '',
            $instance,
            $this->id_base
        );
        $count = (int) ($instance['count'] ?? 5);

        echo $args['before_widget'];

        if ($title) {
            echo $args['before_title'] . esc_html($title) . $args['after_title'];
        }

        $posts = get_posts(['numberposts' => $count, 'post_status' => 'publish']);
        if ($posts) {
            echo '<ul class="myplugin-recent-list">';
            foreach ($posts as $post) {
                printf(
                    '<li><a href="%s">%s</a></li>',
                    esc_url(get_permalink($post)),
                    esc_html(get_the_title($post))
                );
            }
            echo '</ul>';
        }

        echo $args['after_widget'];
    }

    // 管理画面フォーム
    public function form(array $instance): void {
        $title = $instance['title'] ?? '最近の投稿';
        $count = $instance['count'] ?? 5;
        ?>
        <p>
            <label for="<?php echo esc_attr($this->get_field_id('title')); ?>">タイトル:</label>
            <input type="text"
                   id="<?php echo esc_attr($this->get_field_id('title')); ?>"
                   name="<?php echo esc_attr($this->get_field_name('title')); ?>"
                   value="<?php echo esc_attr($title); ?>"
                   class="widefat">
        </p>
        <p>
            <label for="<?php echo esc_attr($this->get_field_id('count')); ?>">表示件数:</label>
            <input type="number"
                   id="<?php echo esc_attr($this->get_field_id('count')); ?>"
                   name="<?php echo esc_attr($this->get_field_name('count')); ?>"
                   value="<?php echo esc_attr($count); ?>"
                   min="1" max="20" class="tiny-text">
        </p>
        <?php
    }

    // 保存処理
    public function update(array $new_instance, array $old_instance): array {
        return [
            'title' => sanitize_text_field($new_instance['title'] ?? ''),
            'count' => absint($new_instance['count'] ?? 5),
        ];
    }
}

ステップ2:ウィジェットを登録する

// functions.php またはプラグインファイル
add_action('widgets_init', function(): void {
    register_widget('Myplugin_Recent_Posts_Widget');
});

ステップ3:カスタムウィジェットエリア(サイドバー)を登録する

// テーマの functions.php でサイドバーを登録
add_action('widgets_init', function(): void {
    register_sidebar([
        'id'            => 'myplugin-sidebar',
        'name'          => 'プラグイン専用サイドバー',
        'description'   => 'プラグインのカスタムサイドバー',
        'before_widget' => '<section id="%1$s" class="widget %2$s">',
        'after_widget'  => '</section>',
        'before_title'  => '<h3 class="widget-title">',
        'after_title'   => '</h3>',
    ]);
});

// テンプレートでサイドバーを表示
if (is_active_sidebar('myplugin-sidebar')) {
    dynamic_sidebar('myplugin-sidebar');
}

ステップ4:WP-CLIでウィジェットを管理する

# 登録済みサイドバー一覧を確認
wp sidebar list --format=table

# ウィジェット一覧を確認
wp widget list sidebar-1 --format=table

# ウィジェットをサイドバーに追加
wp widget add myplugin_recent_posts sidebar-1 1 \
  --title="最近の投稿" --count=5

# ウィジェットの設定を更新
wp widget update {WIDGET_ID} --title="新しいタイトル"

# ウィジェットを削除
wp widget delete {WIDGET_ID}

ステップ5:ブロックウィジェット(WordPress 5.8以降)に対応する

// ブロックウィジェットエディターを無効化して旧エディターに戻す場合
add_filter('use_widgets_block_editor', '__return_false');

// ブロックとしてウィジェット相当の機能を実装(推奨)
// → 0279-plugin-custom-block を参照

注意事項

  • WordPress 5.8以降はブロックウィジェットエディターがデフォルトです。WP_Widget は動作しますが、新規開発ではブロック実装を検討してください
  • widget() メソッド内では必ず esc_html() / esc_url() でサニタイズしてください
  • ウィジェットIDはサイト内でユニークにする必要があります

まとめ

カスタムウィジェットは WP_Widget を継承し widgets_init フックで register_widget() を呼ぶだけで追加できます。wp widget list でWP-CLIから設定確認・追加・更新が可能です。新規開発ではGutenbergブロックとしての実装も検討しましょう。

お気軽にご相談ください

お見積りへ お問い合わせへ