この機能が登場した背景

WordPressのブロックエディタ(Gutenberg)が登場してから7年半。カスタムブロックを作るにはReactを学び、NPMパッケージを管理し、ビルドパイプラインを構築する必要がありました。「ブロック1つ作るためにそこまで必要なのか」と感じた開発者も多いはずです。

WordPress 7.0では、この参入障壁をPHP一行で下げます。supportsにautoRegister => trueフラグを追加するだけで、WordPressがクライアントサイド登録とエディタプレビューに必要なJavaScriptを自動生成します。

本記事はWordPress 7.0のPHP専用ブロック登録機能を扱います。根拠資料としてCSS-TricksのPHP Block Registration記事を参照しています。

重要なのは、**「新規ブロック作成のツールではなく、レガシーPHPコードをブロックテーマへ移行するための橋渡し」**という位置づけです。この観点を外すと実務で遠回りになります。

Developer writing PHP code to register WordPress block without JavaScript IT Technology Image

基本: PHPだけでブロックを登録する

最もシンプルなHello Worldブロックから見ていきます。render_callbackとsupports.autoRegisterだけで完結します。

function css_tricks_hello_world_block() {
    register_block_type(
        'css-tricks/hello-world',
        [
            'title' => 'Hello World',
            'render_callback' => function () {
                return sprintf(
                    '<div %s>Hello World!</div>',
                    get_block_wrapper_attributes()
                );
            },
            'supports' => [
                'autoRegister' => true, // JS自動生成のトリガー
            ],
        ]
    );
}
add_action('init', 'css_tricks_hello_world_block');

属性(Attributes)の追加

従来は属性定義とエディタコントロールUIをJavaScriptで実装する必要がありましたが、PHP専用登録ではattributes配列を定義するだけで、WordPressがサイドバーに入力コントロールを自動生成します。

'attributes' => [
    'greeting' => [
        'type' => 'string',
        'default' => 'Hello World!',
    ],
],

対応する型はstring、number、booleanの3種類のみで、マッピングされるUIはテキスト入力、数値入力、チェックボックス、ドロップダウンの4種類です。画像アップロードやリッチテキストエディタは未対応です。

エディタレンダーとフロントレンダーの判別

is_admin()はRESTエンドポイントではtrueを返さないため使えません。代わりにwp_is_rest_endpoint()とrest_routeを組み合わせます。

if ( wp_is_rest_endpoint()
    && str_contains($GLOBALS['wp']->query_vars['rest_route'] ?? '', 'v2/block-renderer/')
) {
    $frontend = false; // エディタプレビュー
} else {
    $frontend = true;  // フロントエンド
}

現在の投稿IDへのアクセス(ワークアラウンド)

REST APIはステートレスなため、エディタプレビューではget_the_ID()が動作しません。initフックの時点で$_GET['post']を読み取り、role => 'local'属性として渡す回避策を用います。

'attributes' => [
    'postId' => [
        'type' => 'integer',
        'default' => isset($_GET['post']) ? absint($_GET['post']) : 0,
        'role' => 'local', // サイドバーUI生成を抑制
    ],
],

ただし新規投稿作成時はURLにIDが存在しないため、保存後にフルリロードするまで動作しません。Coreで正式サポートが実装されるまでの暫定策です。

Server-side rendering of WordPress block via REST API endpoint Algorithm Concept Visual

必ず理解すべき制約

制約影響実務対応
ブロックコンテンツ内のインタラクション不可エディタプレビューでインライン編集不可、サイドバーコントロールのみ静的レンダーブロックに限定
プレビューマークアップにJSイベントを接続不可スライダー/カルーセル等のDOM操作ライブラリが使えないフロントエンドのみJS使用(view_script)
フレッシュデータへアクセス不可エディタでタイトル変更してもブロックはDB値を表示タイトル/本文/抜粋/アイキャッチ表示ブロックに不適
投稿コンテキストなしthe_title()、get_post_meta()等のテンプレートタグが使えない上記ワークアラウンドまたは静的ブロックのみ
属性型の制限(string/number/boolean)画像アップロード、日付ピッカー、リッチテキスト不可複雑なUIはJavaScriptブロックで
ドロップダウンのkeyed array非対応ラベル≠保存値のマッピング不可(カテゴリslug保存→名前変更で破損)安定した識別子が必要ならJSブロックで

⚠️ 注意事項: これらの制約はアーキテクチャ由来のもので、近い将来変わる予定はありません。「そのうち改善されるだろう」と新規ブロックをPHP専用で作るべきではありません。

ではどこで使うか — レガシー移行

この機能のキラーユースケースはクラシックテーマのPHPコードをブロックテーマへ移行することです。

  • レガシーウィジェット → ブロック(サイドバー設定UIで再現可能)
  • ショートコード → ブロック(ブロックテンプレート内のショートコードは扱いにくい)
  • テンプレートパーツ/カスタムテンプレートタグ → ブロック(ヘッダー、フッター、著者紹介、関連記事)
  • フロントエンドのみで動作するカスタム機能

エディタプレビューが完璧でなくても構いません。フロントエンドで正しくレンダリングされれば十分です。実際、ヘッダーをPHPブロックでラップすることでテーマ移行を数日→数時間に短縮した事例があります。

実務Tips

  • CSS登録: wp_register_style() → 'style'(フロント+エディタ)または'editor_style'(エディタ専用オーバーライド)
  • JS登録: view_scriptで登録すると該当ブロックがあるページでのみロード(フロント専用)
  • クラス命名: WordPressが自動生成する.wp-block-{namespace}-{name}をルートクラスとして使用。BEM方式を推奨
  • iframeエディタ: Block API Version 3以上でiframeモード。WordPress 7.1で強制されるため、事前にv3へ揃えておく
  • 有用なsupports: inserter => false(インサーター非表示)、multiple => false(単一インスタンス)、align => true(整列オプション)

日本の開発エコシステムにおける適用文脈

日本の制作会社・受託開発では、保守契約付きのレガシーWordPressサイトが多数存在します。クライアントが「ブロックテーマにしたい」と希望しても、既存のカスタムPHPウィジェットやショートコードが足枷になるケースが頻繁にあります。本機能はそうした案件で**「全面リプレイスなしでブロックテーマへ移行」**という選択肢を生み出します。ただしエディタUXへの期待値が高いクライアント(例:コンテンツチームが直接編集するサイト)では、サイドバーコントロールだけでは不足する可能性があるため、インタラクティブブロックはJavaScriptで並行開発するハイブリッド戦略を推奨します。Qiitaでも「ブロック開発の学習コストが高い」という議論が長く続いてきましたが、この機能はその議論に対する現実的な答えの一つと言えるでしょう。

WordPress admin editor showing PHP-only registered block with sidebar settings System Abstract Visual

まとめ: 7年半待った甲斐はあったか

新規の機能性ブロックを作るなら → No。 WordPressユーザーが期待するネイティブな編集体験はJavaScriptなしでは実現できません。PHP専用登録はJavaScriptブロックを代替せず、代替すべきでもありません。

レガシーPHPコードのせいでクラシックテーマに縛られたサイトを移行するなら → Yes。 ショートコード、ウィジェット、テンプレートパーツを、すでに持っているPHPスキルだけでブロックエディタへ移植できます。JavaScriptも、ビルドパイプラインも、コード重複も不要です。

この機能が本当に意味するのは、**「WordPress Coreがようやく開発者体験(DX)を優先し始めた」**というシグナルです。JavaScriptブロック開発にもボイラープレートが多く、block.json–PHP–JS間の調整コストが大きいのが実情ですから。

次のステップ学習方向

  1. Block API Version 3への移行 — WordPress 7.1のiframe強制に備える
  2. block.jsonメタデータ構造の理解 — PHP専用からJavaScriptブロックへ自然に拡張する橋渡し
  3. @wordpress/scriptsビルド環境 — インタラクティブブロックが必要になった瞬間に必須
  4. Block Supports API全体のスペック — テーマtheme.jsonとの相互作用を理解

あわせて読みたい記事

本コンテンツは、信頼性の高い情報源をもとにAIツールを活用して作成され、編集者によるレビューを経て公開されています。専門家によるアドバイスの代替となるものではありません。