2026年5月20日
2026年5月20日
WordPressプラグインでカスタムブロックを作成する方法
はじめに
GutenbergのカスタムブロックはJavaScript(React)またはPHP(Dynamic Block)で作成できます。PHPのDynamic Blockは既存のPHP知識を活かして動的コンテンツをブロックとして提供できます。
症状・原因
- Gutenbergエディターに独自のブロックを追加したい
- 最新投稿・カウントダウン・CTAなどの動的コンテンツをブロック化したい
- block.jsonを使ったモダンなブロック登録方法を知りたい
- WP-CLIのスキャフォールドでブロックの雛形を生成したい
解決手順
ステップ1:WP-CLIでブロックの雛形を生成する
# カスタムブロックの雛形を自動生成
wp scaffold block my-cta \
--title="CTAブロック" \
--category=common \
--plugin=my-plugin
# 生成されるファイル:
# blocks/my-cta/
# ├── block.json # ブロックのメタデータ
# ├── index.js # エディター側のJS
# ├── editor.css # エディター用CSS
# ├── style.css # フロントエンド用CSS
# └── render.php # PHPレンダリング(Dynamic Block)
ステップ2:block.jsonを作成する
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "myplugin/cta-block",
"version": "1.0.0",
"title": "CTAブロック",
"category": "text",
"description": "コール・トゥ・アクションブロック",
"supports": {
"html": false,
"align": ["wide", "full"]
},
"attributes": {
"heading": {
"type": "string",
"default": "お問い合わせはこちら"
},
"buttonText": {
"type": "string",
"default": "お問い合わせ"
},
"buttonUrl": {
"type": "string",
"default": "/contact/"
},
"backgroundColor": {
"type": "string",
"default": "#0073aa"
}
},
"textdomain": "myplugin",
"editorScript": "file:./index.js",
"editorStyle": "file:./editor.css",
"style": "file:./style.css",
"render": "file:./render.php"
}
ステップ3:PHPでDynamic Blockを登録する
// プラグインファイル
add_action('init', function(): void {
// block.json からブロックを登録(推奨)
register_block_type(__DIR__ . '/blocks/cta-block');
});
// blocks/cta-block/render.php — ブロックのHTML出力
// $attributes: block.jsonで定義した属性値
// $content: インナーブロックのコンテンツ
// $block: WP_Block インスタンス
$heading = esc_html($attributes['heading'] ?? 'お問い合わせはこちら');
$btn_text = esc_html($attributes['buttonText'] ?? 'お問い合わせ');
$btn_url = esc_url($attributes['buttonUrl'] ?? '/contact/');
$bg_color = esc_attr($attributes['backgroundColor'] ?? '#0073aa');
$wrapper = get_block_wrapper_attributes(['style' => "background-color:{$bg_color}"]);
?>
<div <?php echo $wrapper; ?>>
<h2 class="cta-heading"><?php echo $heading; ?></h2>
<a href="<?php echo $btn_url; ?>" class="cta-button"><?php echo $btn_text; ?></a>
</div>
ステップ4:JavaScriptでエディター側のUIを作る
// blocks/cta-block/index.js
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, InspectorControls, RichText } from '@wordpress/block-editor';
import { PanelBody, TextControl, ColorPicker } from '@wordpress/components';
import metadata from './block.json';
registerBlockType(metadata.name, {
edit({ attributes, setAttributes }) {
const { heading, buttonText, buttonUrl, backgroundColor } = attributes;
const blockProps = useBlockProps({
style: { backgroundColor }
});
return (
<>
<InspectorControls>
<PanelBody title="ボタン設定">
<TextControl label="ボタンURL" value={buttonUrl}
onChange={v => setAttributes({ buttonUrl: v })} />
<ColorPicker color={backgroundColor}
onChange={v => setAttributes({ backgroundColor: v })} />
</PanelBody>
</InspectorControls>
<div {...blockProps}>
<RichText tagName="h2" value={heading}
onChange={v => setAttributes({ heading: v })}
placeholder="見出しを入力..." />
<RichText tagName="a" value={buttonText}
onChange={v => setAttributes({ buttonText: v })}
placeholder="ボタンテキスト..." />
</div>
</>
);
},
save: () => null, // Dynamic Blockはsaveでnullを返す
});
ステップ5:WP-CLIでブロックを確認する
# 登録済みブロックを確認
wp eval "print_r(array_keys(WP_Block_Type_Registry::get_instance()->get_all_registered()));" \
| grep myplugin
# ブロックのメタデータを確認
wp eval "var_dump(WP_Block_Type_Registry::get_instance()->get_registered('myplugin/cta-block'));"
# ブロックを使用している投稿を検索
wp post list --format=ids | xargs -I{} wp post get {} --field=post_content | \
grep -l 'wp:myplugin/cta-block'
ステップ6:ビルド環境を整える
# @wordpress/scripts を使ったビルド環境
npm init -y
npm install --save-dev @wordpress/scripts
# package.json に追加
# "scripts": {
# "build": "wp-scripts build",
# "start": "wp-scripts start"
# }
npm run build # 本番用ビルド(src/ → build/)
npm run start # 開発サーバー起動(ホットリロード)
注意事項
- Dynamic Block(
save: () => null)はサーバーサイドでレンダリングするため、キャッシュに注意してください block.jsonの"render": "file:./render.php"を使うとJSのsave関数が不要になります(WordPress 6.1以降)get_block_wrapper_attributes()を使うとclassName・style属性をGutenbergから自動適用できます
まとめ
block.json でブロックのメタデータを定義し、register_block_type(__DIR__ . '/blocks/cta-block') で登録します。PHPの render.php でDynamic Blockとして実装すると、React不要でサーバーサイドの動的コンテンツをGutenbergブロック化できます。