WordPress 7.0 から、PHP だけでシンプルなブロックを登録できる仕組みが追加されました。
正確には、register_block_type() に supports.autoRegister と render_callback を指定することで、JavaScript 側で registerBlockType() を書かなくても、ブロックエディター上にブロックを表示できるようになった、というものです。
公式の開発者向け記事では「PHP-only block registration」として紹介されています。
この記事は、2026年7月18日時点で確認できる WordPress 7.0 系の公式情報をもとに書いています。今後の WordPress や Gutenberg の更新によって、対応できる属性や編集 UI の範囲が変わる可能性はあります。
参考資料
個人的には、この機能は「これからブロック開発が全部 PHP だけで完結します」という話ではないと考えています。むしろ、もう少し現場寄りに言うと、これまでカスタムフィールドで無理やりページ編集欄を作っていたような制作から、少しずつブロックらしい編集体験へ移っていくための助けになるのではないか、と感じています。
もちろん、すべてのカスタムフィールドを置き換えられるわけではありません。
ただ、「PHP なら書けるけれど、React やブロックエディター向けの JavaScript まではなかなか手が出しづらい」という方にとって、かなり現実的な入口になる可能性があります。
これまでの「カスタムフィールド製造業」的な制作
WordPress の制作現場では、長いあいだカスタムフィールドが便利に使われてきました。
たとえば、固定ページごとに、
- メインビジュアルの画像
- キャッチコピー
- 説明文
- ボタンの文言
- ボタンのリンク先
- 表示・非表示の切り替え
- 背景色
- 並び順
といった入力欄を管理画面側に用意して、テンプレート側でそれらの値を読み取り、ページを組み立てるような作り方です。
この方法自体が悪いわけではありません。案件によっては今でも有効ですし、運用者に触ってほしい範囲を厳密に制限できるというメリットもあります。
ただ、使い方によっては「本文を編集するための WordPress」ではなく、「カスタムフィールドに値を入れるための管理画面」になってしまうことがあります。
ページの内容を変えたいだけなのに、本文エリアではなく、テーマやプラグイン側で用意された大量の入力欄を探して編集する。レイアウトの一部を追加したいだけなのに、そもそもその入力欄が用意されていないから修正できない。こういった状態は、制作側も運用側も少しずつ苦しくなっていきます。
ブロックエディターが登場して以降、本来であれば「ページを構成する部品」はブロックとして扱うほうが自然になってきました。
しかし、現実にはブロック開発の入口が少し高く感じられる場面もあります。PHP でテンプレートを書くことには慣れていても、ビルド環境を用意して、block.json を書いて、React コンポーネントとして edit や save を実装して、という流れになると、なかなか腰が重くなるのもわかります。
そこで今回の PHP-only block registration です。
PHP-only block registration とは
PHP-only block registration は、サーバーサイドレンダリングされるシンプルなブロックを、PHP の register_block_type() だけで登録できる仕組みです。
ポイントは次の2つです。
supportsにautoRegisterを指定するrender_callbackを指定する
この2つを指定すると、JavaScript 側でブロックを登録しなくても、ブロックエディター上にそのブロックが表示されます。そして、エディター上でもフロントエンドでも、PHP の render_callback によって出力が生成されます。
参考資料:Registration of a block – Block Editor Handbook、Supports – Block Editor Handbook
最小構成に近いコードは、以下のようになります。
add_action( 'init', function () {
register_block_type(
'my-plugin/example',
array(
'title' => __( 'Example Block', 'my-plugin' ),
'attributes' => array(
'title' => array(
'label' => __( 'Title', 'my-plugin' ),
'type' => 'string',
'default' => __( 'Hello World', 'my-plugin' ),
),
),
'render_callback' => function ( $attributes ) {
$wrapper_attributes = get_block_wrapper_attributes();
return sprintf(
'<div %1$s><p>%2$s</p></div>',
$wrapper_attributes,
esc_html( $attributes['title'] )
);
},
'supports' => array(
'autoRegister' => true,
),
)
);
} );
これだけで、ブロックエディターにブロックが登録されます。
従来のブロック開発に比べると、かなり PHP 寄りの書き味です。テンプレートタグや render_callback に慣れている方であれば、「なるほど、こういうことか」とつかみやすいのではないでしょうか。
渡せる主なパラメータ
register_block_type() の第2引数には、ブロックタイプの設定を配列で渡します。PHP-only block registration だからといって、まったく別の API が用意されたわけではありません。通常の register_block_type() の仕組みに、supports.autoRegister が加わったと考えるとわかりやすいです。
主に使いそうな項目を挙げると、以下のようになります。
| パラメータ | 役割 |
|---|---|
title | ブロックの表示名 |
category | ブロックインサーターでの分類 |
description | ブロックの説明 |
icon | ブロックのアイコン |
keywords | ブロック検索用のキーワード |
attributes | ブロックが持つデータの定義 |
supports | 色、余白、配置などのブロックサポート設定 |
render_callback | PHP で HTML を出力する関数 |
styles | ブロックスタイル |
example | プレビュー用のサンプルデータ |
もう少し細かく見ると、parent、ancestor、allowed_blocks、uses_context、provides_context、block_hooks、variations、selectors、各種スクリプト・スタイルのハンドルなども、WP_Block_Type が受け取れる項目として扱われます。
ただ、PHP-only block registration の文脈で最初から全部を使おうとすると、かえってわかりにくくなります。
この中でも、PHP-only block registration で特に重要なのは attributes、render_callback、supports です。
attributes でブロックが持つ設定値を定義し、render_callback でその値を使って HTML を返します。そして supports の中で autoRegister を true にします。
参考資料
- register_block_type() – WordPress Developer Resources
- WP_Block_Type::__construct() – WordPress Developer Resources
- Metadata in block.json – Block Editor Handbook
自動で Inspector Controls が作られる属性
この機能のおもしろいところは、属性の定義から、可能な範囲で Inspector Controls の入力 UI が自動生成される点です。
たとえば、以下のような属性を定義できます。
'attributes' => array(
'title' => array(
'label' => __( 'Title', 'my-plugin' ),
'type' => 'string',
'default' => '',
),
'count' => array(
'label' => __( 'Count', 'my-plugin' ),
'type' => 'integer',
'default' => 3,
),
'enabled' => array(
'label' => __( 'Enabled?', 'my-plugin' ),
'type' => 'boolean',
'default' => true,
),
'size' => array(
'label' => __( 'Size', 'my-plugin' ),
'type' => 'string',
'enum' => array( 'small', 'medium', 'large' ),
'default' => 'medium',
),
),
公式情報や実装を確認する限り、現時点で自動生成の対象になる属性タイプは次の4つです。
stringnumberintegerboolean
また、source を持つ属性や、role が local の属性は、自動生成されるコントロールの対象外になります。
ここは大事なところです。
通常のブロック開発では、HTML から値を取り出すために source や selector を使うことがあります。しかし、PHP-only block registration の自動コントロールは、そういった HTML 由来の属性ではなく、ブロックコメント内の JSON に保存されるシンプルな属性を前提にしていると考えると良さそうです。
参考資料
ブロックサポートも使える
PHP-only block registration では、通常のブロックサポートも組み合わせることができます。
たとえば、背景色を変更できるようにしたい場合は、以下のように指定できます。
'supports' => array(
'autoRegister' => true,
'color' => array(
'background' => true,
'text' => true,
),
),
このようなブロックサポートを使う場合、出力側では get_block_wrapper_attributes() を使って、生成されたクラス名やスタイル属性をラッパー要素に反映させることが大切です。
'render_callback' => function ( $attributes ) {
return sprintf(
'<div %1$s>%2$s</div>',
get_block_wrapper_attributes(),
esc_html( $attributes['title'] ?? '' )
);
},
ここを忘れると、エディター上で設定した色や余白などが、フロントエンドの HTML にうまく反映されない場合があります。
ブロックサポートを使えるという点は、カスタムフィールド中心の実装と比べたときに大きな違いです。
カスタムフィールドで「背景色」や「余白」や「配置」を個別に作り込むのではなく、WordPress が用意しているブロックの共通機能に乗せられる。これは、制作側にとっても運用側にとっても、地味ですがかなり大きい変化だと思います。
参考資料
実装時に気をつけたいこと
PHP で HTML を返す以上、出力時のエスケープはこれまで通り必要です。
render_callback の中では、属性の値をそのまま出すのではなく、内容に応じて esc_html()、esc_attr()、esc_url() などを使います。
'render_callback' => function ( $attributes ) {
$url = $attributes['url'] ?? '';
$label = $attributes['label'] ?? '';
return sprintf(
'<a %1$s href="%2$s">%3$s</a>',
get_block_wrapper_attributes(),
esc_url( $url ),
esc_html( $label )
);
},
また、属性が必ず存在するとは限らない前提で書いておくほうが安心です。default を指定していても、将来的な変更や過去データとの兼ね合いで、想定していない値が入る可能性はあります。
このあたりは、従来のテーマ・プラグイン開発と同じ感覚で、少し丁寧に扱いたいところです。
どんな用途に向いているか
この機能は、複雑なブロックを作るためのものではありません。向いているのは、比較的シンプルで、PHP 側で出力が完結するブロックです。
たとえば、次のようなものです。
- CTA ブロック
- 著者プロフィールブロック
- 関連記事を表示するブロック
- 特定条件の投稿一覧ブロック
- 営業時間や店舗情報を出すブロック
- ショートコードで出していた内容を置き換えるブロック
- テーマ内で使う小さな専用パーツ
これまでであれば、ショートコードを作ったり、カスタムフィールドで入力欄を用意したり、固定ページテンプレートに直接組み込んだりしていたようなものです。
そういったものを「ブロック」として登録できるようになると、編集者は本文の中でその部品を扱えるようになります。
これは単に実装方法が変わるだけではありません。
運用者にとっては、「このページのこの場所に、このパーツを置く」という感覚に近づきます。制作側にとっても、テンプレート側に編集項目を増やし続けるのではなく、必要な部品をブロックとして提供する方向に考えやすくなります。
カスタムフィールドを否定する話ではない
念のため書いておくと、これはカスタムフィールドを否定する話ではありません。
カスタムフィールドには、今でも明確な役割があります。
たとえば、投稿やページに紐づく構造化データを管理したい場合、検索条件や絞り込み条件として使いたい場合、テーマの裏側で固定的に扱うメタ情報を持たせたい場合などです。
こういったものは、無理にブロックへ寄せる必要はないでしょう。
一方で、ページ本文の中に出てくるコンテンツや、レイアウトの一部として扱うパーツまで、すべてカスタムフィールドで管理しようとすると、WordPress の編集体験から少し離れてしまいます。
僕自身も、カスタムフィールドを使った制作には何度も助けられてきました。特に、ブロックエディター以前の制作では、かなり現実的な選択肢だったと思います。
ただ、今後も同じ作り方を続けるべきかというと、そこは少し立ち止まって考えたいところです。
- 「これは本当にカスタムフィールドであるべきなのか」
- 「本文の中で扱えるブロックにしたほうが、運用しやすいのではないか」
- 「ショートコードではなく、ブロックとして提供できないか」
そういった判断をする場面が、これから少しずつ増えていくのではないかと思っています。
できないことも多い
ただし、PHP-only block registration は万能ではありません。
現時点では、かなり制限があります。
- 画像選択やファイル選択のような複雑な UI は自動生成されない
textarea的な入力を前提にしたリッチな編集には向かないobjectやarrayのような複雑な属性は自動コントロールの対象外- InnerBlocks を使うコンテナブロックには向かない
- エディター上の反応はサーバーサイドレンダリングに依存する
- JavaScript 側で細かい編集体験を作り込むことはできない
ですので、たとえば「複数の子ブロックを内包するセクションブロック」や「画像を選んで、その場でプレビューを細かく制御するブロック」などを作りたい場合は、従来通り JavaScript を使ったブロック開発を選ぶことになると思います。
この機能は、ブロック開発のすべてを PHP に戻すものではありません。
むしろ、PHP で十分な領域に対して、ちゃんとブロックという形を与えられるようになった、と考えるほうが自然です。
参考資料
小さく始めるなら、ショートコードの置き換えから
個人的に、最初に試すならショートコードの置き換えが良いのではないかと思っています。
たとえば、これまで以下のようなショートコードを使っていたとします。
[latest_posts count="3"]
これを PHP-only ブロックとして用意すれば、編集者はショートコードの文字列を覚えなくても、ブロックとして挿入できます。
count のような数値設定は Inspector Controls 側で変更できるようにできますし、ブロックサポートを使えば、背景色や余白なども WordPress の標準的な操作に寄せられます。
ショートコードは便利ですが、編集画面上では「ただの文字列」になりがちです。ブロックにすると、少なくとも「ここに何かの部品が入っている」ということが見えやすくなります。これは運用上、かなり大きな違いです。
制作側の考え方も少し変わる
この機能が入ったことで、制作側の考え方も少し変えられるかもしれません。
これまでは、PHP 中心の制作では、
- テンプレートを作る
- カスタムフィールドを作る
- その値をテンプレートに出す
という流れが自然でした。
しかし、これからは一部のパーツについて、
- ブロックとして登録する
- 必要な属性だけを持たせる
- 出力は PHP で行う
- 編集者は本文中でブロックとして扱う
という選択肢が取りやすくなります。
これは、制作方法の大きな転換というよりも、選択肢がひとつ増えたという感覚です。
全部をいきなりブロック化する必要はありません。既存の制作フローを全部捨てる必要もありません。
ただ、次に何か小さな専用パーツを作るときに、「これはカスタムフィールドではなく、PHP-only ブロックで良いのでは?」と考えられるようになる。その入口ができたことに意味があると思います。
まとめ
PHP-only block registration は、WordPress 7.0 で追加された、サーバーサイドレンダリング向けのシンプルなブロック登録方法です。
register_block_type() に supports.autoRegister と render_callback を指定することで、JavaScript の登録コードを書かなくても、PHP だけでブロックをエディターに表示できるようになります。
もちろん、できることは限られています。複雑な編集 UI や InnerBlocks を使うブロックには向きません。リッチなブロックを作るなら、これまで通り JavaScript を使った開発が必要です。
それでも、これまでショートコードやカスタムフィールドで作っていた小さな表示パーツを、ブロックとして扱えるようになる意味は大きいと感じています。
カスタムフィールドは便利です。しかし、ページ本文の編集体験までカスタムフィールドに寄せすぎると、WordPress が本来持っているブロックエディターの良さを活かしづらくなる場合があります。
PHP-only block registration は、その間にある小さな橋のような機能かもしれません。
PHP で書ける範囲のものから、少しずつブロックとして提供していく。そうすることで、制作側も運用側も、無理なくブロックエディターに近づいていけるのではないかと思います。
次にショートコードやカスタムフィールドを追加しそうになったときに、一度だけ「これは PHP-only ブロックにできないだろうか」と考えてみる。
まずはそのくらいの距離感から試してみるのが、ちょうど良いのではないでしょうか。
主な参考資料
- PHP-only block registration – Make WordPress Core
- Registration of a block – Block Editor Handbook
- register_block_type() – WordPress Developer Resources
- WP_Block_Type::__construct() – WordPress Developer Resources
- Metadata in block.json – Block Editor Handbook
- Attributes – Block Editor Handbook
- Supports – Block Editor Handbook
- Trac #64639: Allow PHP-Only Block Registration













