2026年5月20日

2026年5月20日

WordPressのカスタムブロックをプラグインで作る方法(create-block・block.json・render.php)

ブロックエディター(Gutenberg)のブロックは、プラグインで追加できます。いまの標準的な作り方は、ブロックの情報を block.json に書き、エディターでの見た目を JavaScript(React)で、公開ページの HTML を PHP の render.php で作る方法です。PHP で出力するブロックを「ダイナミックブロック」と呼びます。

この記事では、見出しとボタンを並べた「CTA ブロック」を作ります。手順とコードは、2026年11月時点の WordPress 7.1、Node.js 22、@wordpress/create-block の最新版で、ビルドと表示まで確かめました。

用意するもの

  • Node.js と npm(ブロックの JavaScript をビルドするため。この記事は Node.js 22 で確認)
  • WordPress が動くローカル環境(作ったプラグインを入れて確かめるため)

なお、WP-CLI の wp scaffold block コマンドは非推奨になっています(wp help scaffold block にも、公式の @wordpress/create-block を使うよう書かれています)。この記事では create-block を使います。

1. create-block で雛形を作る

wp-content/plugins フォルダーで次のコマンドを実行します。

cd wp-content/plugins
npx @wordpress/create-block@latest my-cta --variant dynamic --namespace myplugin --title "CTA Block"
オプション 意味
my-cta プラグインのフォルダー名(ブロック名の後半にもなる)
--variant dynamic PHP(render.php)で出力するダイナミックブロックの雛形にする
--namespace myplugin ブロック名の前半。ブロック名は myplugin/my-cta になる
--title ブロックの表示名

必要なパッケージのインストールと最初のビルドまで自動で行われ、次のファイルができます(主なもの)。

my-cta/
├── my-cta.php            # プラグイン本体(ブロックを登録する)
├── package.json          # ビルドのコマンド
├── src/my-cta/
│   ├── block.json        # ブロックの情報
│   ├── index.js          # ブロックの登録(JS)
│   ├── edit.js           # エディターでの表示と操作
│   ├── render.php        # 公開ページの HTML
│   ├── style.scss        # 公開ページとエディター共通の CSS
│   ├── editor.scss       # エディターだけの CSS
│   └── view.js           # 公開ページで動かす JS(使わなければ削除してよい)
└── build/                # ビルド結果(WordPress が読むのはこちら)

編集するのは src の中のファイルです。build はビルドのたびに作り直されます。

2. プラグイン本体でブロックを登録する

生成された my-cta.php は、次のように(ヘッダーとコメントは一部省略) build フォルダーのブロックをまとめて登録します。

<?php
/**
 * Plugin Name:       CTA Block
 * Requires at least: 6.8
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

function myplugin_my_cta_block_init() {
	wp_register_block_types_from_metadata_collection( __DIR__ . '/build', __DIR__ . '/build/blocks-manifest.php' );
}
add_action( 'init', 'myplugin_my_cta_block_init' );

wp_register_block_types_from_metadata_collection() は WordPress 6.8 で追加された関数で、ビルド時に作られる blocks-manifest.php を使って、複数のブロックを効率よく登録します。ブロックが1つだけなら、従来の書き方 register_block_type( __DIR__ . '/build/my-cta' ); でも登録できます。

3. block.json で属性と機能を決める

src/my-cta/block.json を次のように書き換えます。

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "myplugin/my-cta",
	"version": "0.1.0",
	"title": "CTAブロック",
	"category": "widgets",
	"icon": "megaphone",
	"description": "見出しとボタンを並べた、お問い合わせへの誘導ブロック",
	"attributes": {
		"heading": {
			"type": "string",
			"default": "お気軽にご相談ください"
		},
		"buttonText": {
			"type": "string",
			"default": "お問い合わせ"
		},
		"buttonUrl": {
			"type": "string",
			"default": ""
		}
	},
	"supports": {
		"html": false,
		"align": [ "wide", "full" ],
		"color": {
			"background": true,
			"text": true
		},
		"spacing": {
			"padding": true
		}
	},
	"textdomain": "my-cta",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css",
	"render": "file:./render.php"
}

主な項目の意味です。

  • attributes: ブロックが持つ値です。ここでは見出し・ボタンの文字・リンク先 URL の3つです。値は投稿本文のブロックのコメント(<!-- wp:myplugin/my-cta {...} /-->)に保存されます。既定値のままの属性は保存されず、表示時に default が使われます。
  • supports: WordPress 本体の機能をブロックに付けます。color を有効にすると、背景色と文字色の設定欄がエディターに出て、選んだ色のクラスやスタイルは次の get_block_wrapper_attributes() が自動で付けます。色の属性を自分で作る必要はありません。
  • render: 公開ページの HTML を作る PHP ファイルです(WordPress 6.1 で追加)。これを指定すると、JavaScript 側で保存用の HTML を作る必要がなくなります。
  • editorScript などの file:./: build 内のファイルを指します。ビルド後のファイル名(index.js、style-index.css など)で書きます。

view.js を使わない場合は、src/my-cta/view.js を削除し、block.json から viewScript の行も消します。

4. render.php で公開ページの HTML を作る

src/my-cta/render.php を次のように書きます。

<?php
/**
 * 公開側の HTML を出力する。
 * $attributes(ブロックの属性)、$content(内側のブロック)、$block(WP_Block)が使える。
 */

$heading     = $attributes['heading'] ?? '';
$button_text = $attributes['buttonText'] ?? '';
$button_url  = esc_url( $attributes['buttonUrl'] ?? '' ); // 危険な URL は空になる
?>
<div <?php echo get_block_wrapper_attributes(); ?>>
	<?php if ( '' !== $heading ) : ?>
		<p class="wp-block-myplugin-my-cta__heading"><?php echo wp_kses_post( $heading ); ?></p>
	<?php endif; ?>
	<?php if ( '' !== $button_url && '' !== $button_text ) : ?>
		<a class="wp-block-myplugin-my-cta__button" href="<?php echo $button_url; ?>">
			<?php echo esc_html( $button_text ); ?>
		</a>
	<?php endif; ?>
</div>
  • get_block_wrapper_attributes() は、ブロックのクラス(wp-block-myplugin-my-cta)と、supports で付けた色や余白、配置のクラス・スタイルをまとめて出力します。外側の要素にはこれを付けます。
  • 見出しはエディターで太字やリンクを付けられるので wp_kses_post() で許可されたタグだけを残し、ボタンの文字は esc_html() でエスケープします。
  • URL は先に esc_url() を通します。javascript: で始まるような URL は空になるので、その場合はボタンを出しません。

試しに、背景色に黒・文字色に白を選んだブロックは、次の HTML になりました(空白は整理しています)。

<div class="wp-block-myplugin-my-cta has-text-color has-white-color has-background has-black-background-color">
	<p class="wp-block-myplugin-my-cta__heading">お気軽にご相談ください</p>
	<a class="wp-block-myplugin-my-cta__button" href="https://example.com/contact/">お問い合わせ</a>
</div>

5. edit.js でエディターの表示と操作を作る

src/my-cta/edit.js を次のように書きます。見出しはブロックの中で直接編集し、ボタンの文字と URL は右側の設定サイドバーで入力します。

import { __ } from '@wordpress/i18n';
import { useBlockProps, InspectorControls, RichText } from '@wordpress/block-editor';
import { PanelBody, TextControl } from '@wordpress/components';
import './editor.scss';

export default function Edit( { attributes, setAttributes } ) {
	const { heading, buttonText, buttonUrl } = attributes;

	return (
		<>
			<InspectorControls>
				<PanelBody title={ __( 'ボタンの設定', 'my-cta' ) }>
					<TextControl
						__next40pxDefaultSize
						__nextHasNoMarginBottom
						label={ __( 'ボタンの文字', 'my-cta' ) }
						value={ buttonText }
						onChange={ ( value ) => setAttributes( { buttonText: value } ) }
					/>
					<TextControl
						__next40pxDefaultSize
						__nextHasNoMarginBottom
						type="url"
						label={ __( 'ボタンのリンク先 URL', 'my-cta' ) }
						value={ buttonUrl }
						onChange={ ( value ) => setAttributes( { buttonUrl: value } ) }
					/>
				</PanelBody>
			</InspectorControls>

			<div { ...useBlockProps() }>
				<RichText
					tagName="p"
					className="wp-block-myplugin-my-cta__heading"
					value={ heading }
					onChange={ ( value ) => setAttributes( { heading: value } ) }
					placeholder={ __( '見出しを入力', 'my-cta' ) }
				/>
				<span className="wp-block-myplugin-my-cta__button">
					{ buttonText }
				</span>
			</div>
		</>
	);
}
  • useBlockProps() は、エディター側で外側の要素に付ける属性です。PHP の get_block_wrapper_attributes() に当たり、色や配置の設定がエディターの表示にも反映されます。
  • InspectorControls の中身は、右側の設定サイドバーに表示されます。
  • @wordpress/components は、ビルド時に WordPress 本体の wp.components を使うように変換されるので、追加でインストールしなくてもビルドできました。

src/my-cta/index.js は雛形のままで使えます。ダイナミックブロックなので save を書かず、保存されるのはブロックのコメント(属性)だけです。

import { registerBlockType } from '@wordpress/blocks';
import './style.scss';
import Edit from './edit';
import metadata from './block.json';

registerBlockType( metadata.name, {
	edit: Edit,
} );

6. CSS を書く

src/my-cta/style.scss は公開ページとエディターの両方に読み込まれます。

.wp-block-myplugin-my-cta {
	padding: 2rem;
	text-align: center;

	&__heading {
		margin: 0 0 1rem;
		font-size: 1.25rem;
		font-weight: bold;
	}

	&__button {
		display: inline-block;
		padding: 0.75em 1.5em;
		border-radius: 4px;
		background: #1d2327;
		color: #fff;
		text-decoration: none;
	}
}

エディターだけに付けたい見た目(枠線など)は editor.scss に書きます。

7. ビルドして有効化する

cd my-cta
npm run build   # src をビルドして build に出力する
npm start       # 開発中: ファイルを保存するたびに自動でビルドし直す

ビルドしたら、「プラグイン」画面で「CTA Block」を有効化します。投稿の編集画面でブロックを追加し、「CTAブロック」を検索すると表示されます。

配布用の ZIP ファイルは npm run plugin-zip で作れます。本番サイトに置くのは my-cta.php と build フォルダーで、node_modules と src は不要です。

WP-CLI で確かめる

# ブロックが登録されているか
wp eval 'var_dump( WP_Block_Type_Registry::get_instance()->is_registered( "myplugin/my-cta" ) );'

# このブロックを使っている投稿・固定ページを探す
wp post list --post_type=post,page --s='wp:myplugin/my-cta' --fields=ID,post_title

うまく表示されないとき

  • ブロックが一覧に出ない: npm run build を実行したか、build/my-cta/block.json があるかを確かめます。src だけを編集してビルドしていないと、WordPress には反映されません。
  • 公開ページに何も出ない: block.json の render が file:./render.php になっているか、build/my-cta/render.php があるかを確かめます。PHP のエラーは WP_DEBUG_LOG を有効にしてログで確認します。
  • 色の設定が反映されない: 外側の要素に get_block_wrapper_attributes()(PHP)と useBlockProps()(JS)を付けているか確かめます。
  • ページキャッシュ: ダイナミックブロックの出力は表示のたびに PHP で作られますが、キャッシュ系のプラグインを使っていると、ブロックを直しても古い HTML が表示されることがあります。

関連記事

お気軽にご相談ください

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