Gutenbergは、強力かつ高度にカスタマイズできるエディターへと進化しました。すぐに使える機能だけでなく、豊富なAPIを活用して独自の機能をウェブサイトに簡単に組み込めるようになっています。この拡張性により、高度にパーソナライズされた機能豊富なオンライン体験を構築でき、驚くほど柔軟なカスタマイズが可能です。
この記事では、あまり知られていないものの非常に有効な2つのWordPressの開発機能─「スタイルバリエーション(ブロックスタイルとも呼ばれます)」と「ブロックバリエーション」─をご紹介します。
最初はその便利さが直感的にわからないかもしれませんが、少し使ってみればすぐにその有用性を実感でき、短時間でワークフローに自然に組み込めるようになります。
この記事では、実際のプロジェクトを通して「ブロックバリエーション」が何か、そしてどのように活用できるのかを具体的にご紹介します。記事内のコードをコピー&ペーストし、最後に必要なカスタマイズを加えるだけで、ご自身のWordPressサイトに簡単に実装できます。
プロジェクトに進む前に、まずは前提条件を確認しておきましょう。
- ローカルWordPress開発環境:どの環境でも構いませんが、Kinstaが提供するローカル開発スイートのDevKinstaを強くおすすめします。使いやすく、ローカル環境でWordPressサイトをすばやく立ち上げて管理できるよう、多くの設定や機能が用意されています。
- Node.jsとnpm:ブロックエディターはReactで構築されており、ビルド処理が必要なため必須の要素です。
- 基本的なフロントエンド開発スキル:Node.js、JavaScript(React使用)、PHP、CSSの基本的な理解があると役立ちます。
このプロジェクトは非常に複雑というわけではありませんが、ある程度コードを書く必要があります。完全なコードはGitHubで公開しています。
ブロックスタイル対ブロックバリエーション
ブロックスタイルとブロックバリエーションは、WordPressで開発を行う際に非常に有効な2つの機能です。名前は似ていますが、それぞれの目的や使い方は異なります。
ブロックスタイルは「スタイルバリエーション」とも呼ばれ、事前に用意されたCSSスタイルのセットによって、ブロックの見た目をワンクリックで切り替えることができます。スタイルを登録すると、ブロックのサイドバーにボタンが表示され、ブロックに組み込まれたスタイルセットを簡単に適用できます。スタイルのオン・オフを切り替えたり、エディター内でリアルタイムにプレビューすることも可能です。

スタイルバリエーションはブロックの属性を変更しません。ブロックのラッパー要素にCSSクラスを割り当てることで、外観だけを変更します。
ブロックバリエーションは、属性や内部ブロックを含むプリセットのバージョンを作成できるため、さらに強力な機能です。エディターのブロックインサーターにも表示され、サイト訪問者にはあたかも個別のブロックであるかのように見えます。
ブロックバリエーションを使うことで、ブロックの外観、初期設定、構造を自由にカスタマイズできます。
それでは、これらの機能を活用して、Gutenbergブロックを次のレベルへ引き上げましょう。
画像ブロックのアニメーションポラロイド効果
それでは、ここから実際のプロジェクトを始めていきます。Gutenbergプラグインを使って、コアの画像ブロックを拡張してみます。
- ポラロイドスタイルのバリエーションを実装:設定サイドバーからワンクリックで、画像に魅力的なポラロイド効果を適用できるようにする
- ホバーアニメーションを追加:ポラロイドスタイルの画像に、繊細なホバーアニメーションを加えて演出を強化
- 「アニメーションポラロイド」ブロックバリエーションを作成:ブロックインサーターから、ホバー効果付きのポラロイド画像をあらかじめ設定された形ですぐに挿入できるようにする
それでは、プラグインのセットアップを始めましょう。

環境のセットアップ
まずは、Node.jsを使ってWordPressの開発環境をセットアップする必要があります。ローカルのWordPress開発環境と、最新版のNode.jsおよびnpmがすでにインストールされていることを前提とします。設定に不安がある場合は、Gutenbergプラグインを使ってブロックエディターに機能を追加する方法をご覧ください。
ステップ1. プラグインの基本構造を作る
この説明では、プラグイン名を「Image Hacker」とします。
plugins
ディレクトリに移動し、新しくimage-hacker
フォルダを作成します。このフォルダの中に、プラグインのメインファイルであるimage-hacker.php
と、src
というサブフォルダを作成します。
以下が、プラグインの基本構造の例です。
/wp-content/plugins/
└── /image-hacker/
├── image-hacker.php
└── /src/
ステップ2. PHPコードを作成する
次に、WordPressがプラグインを認識するようにする必要があります。そのためには、以下のコードをimage-hacker.php
に追加します。
<?php
/**
* Plugin Name: Image Hacker
* Description: Adds new features to the core Image block
* Version: 1.0.0
* Author: Your Name
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: image-hacker
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // 直接アクセスされた場合は処理を終了
}
ステップ3. npmの初期化と依存関係のインストール
好みのコマンドラインツールを開き、プラグインのディレクトリに移動します。そこに移動したら、以下のコマンドを実行してください。
npm init -y
このコマンドによって、プロジェクトの依存関係とスクリプトを含む新しいpackage.json
ファイルが初期化されます。
次に、WordPressスクリプトと、webpackやBabelなどのビルドツールをインストールしてください。
npm install @wordpress/plugins @wordpress/scripts --save-dev
このコマンドは、nodeの依存関係を含むnode_modules
フォルダとpackage-lock.json
ファイルを追加するものです。以下の画像は、Visual Studio Codeのプロジェクトの現在の構造を示しています。

次に、package.json
を開き、scripts
プロパティを以下のように変更します。
{
"name": "image-hacker",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"@wordpress/plugins": "^7.25.0",
"@wordpress/scripts": "^30.18.0"
}
}
なお、devDependencies
のバージョンは上記と異なる場合があり、お使いの環境にインストールされている実際のバージョンによって異なります。
ステップ4. プラグインのソースファイルを作成する
次に、プラグインのソースファイルを作成します。src
フォルダに移動し、以下のファイルを追加します。
index.js
style.scss
editor.scss
プラグインの構造は以下のようになります。
/wp-content/plugins/
└── /image-hacker/
├── /node-modules/
├── image-hacker.php
├── package.json
├── package-lock.json
└── /src/
├── index.js
├── style.scss
└── editor.scss
WordPressの管理画面を開き、「プラグイン」画面に移動します。「Image Hacker」プラグインを見つけ、有効化します。
ステップ5. プラグインのファイルにアセットをインクルードする
次に、メインのプラグインファイルにプラグインアセットをインクルードする必要があります。image-hacker.php
に以下を追加してください。
/**
* ブロックエディターのアセットを読み込む
*/
function image_hacker_enqueue_editor_assets() {
$asset_file = include( plugin_dir_path( __FILE__ ) . 'build/index.asset.php');
// 変更を加えたスクリプトを読み込む
wp_enqueue_script(
'image-hacker-script',
plugins_url( 'build/index.js', __FILE__ ),
array( 'wp-plugins', 'wp-edit-post' ),
filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' )
);
// エディター専用のスタイルを読み込む
wp_enqueue_style(
'image-hacker-editor-style',
plugins_url( 'build/editor.css', __FILE__ ),
[],
filemtime( plugin_dir_path( __FILE__ ) . 'build/editor.css' )
);
}
add_action( 'enqueue_block_editor_assets', 'image_hacker_enqueue_editor_assets' );
/**
* フロントエンドとエディターのアセットを読み込む
*/
function image_hacker_enqueue_assets() {
$asset_file = include( plugin_dir_path( __FILE__ ) . 'build/index.asset.php');
// フロントエンドとエディターの両方で使用するスタイルを読み込む
wp_enqueue_style(
'image-hacker-style',
plugins_url( 'build/style-index.css', __FILE__ ),
[],
filemtime( plugin_dir_path( __FILE__ ) . 'build/style-index.css' )
);
}
add_action( 'enqueue_block_assets', 'image_hacker_enqueue_assets' );
このコードが何をするかというと以下の通りです。
enqueue_block_editor_assets
アクションフックは、index.js
スクリプトとeditor.css
ファイルをエンキューenqueue_block_assets
アクションフックはstyle.css
ファイルをエンキュー
このコードには、プラグインの/build/
フォルダにある.js
と.css
のアセットが含まれていることに注意してください。つまり、これを動作させるには、コマンドラインツールでビルドコマンドを実行する必要があります。
npm run build
また、style.scss
というファイルをindex.js
にインポートした場合、コンパイルされた CSSファイルの名前はstyle.css
ではなくstyle-index.css
になることに注意してください。
ブロックスタイルの登録
これで開発環境のセットアップは完了です。いよいよプロジェクトの本題に入り、ブロックスタイルのバリエーションを登録していきましょう。
ブロックスタイルを登録する方法はいくつかあり、目的や好みによって選択が異なります。今回はGutenbergプラグインを作成しているため、JavaScriptを使った方法を採用します。/src/index.js
ファイルを開き、以下のコードを貼り付けてください。
// ブロックスタイルを登録する関数をインポート
import { registerBlockStyle } from '@wordpress/blocks';
// DOMの読み込み完了時にのみコードを実行する関数をインポート
import domReady from '@wordpress/dom-ready';
// ビルド処理でSCSSファイルを読み込みコンパイルするよう指示
import './style.scss';
/**
* domReadyを使って、DOMの読み込みが完了したときにのみコードを実行
*/
domReady(() => {
// コアの画像ブロックに新しいスタイルバリエーションを登録
registerBlockStyle('core/image', {
name: 'polaroid',
label: 'Polaroid',
});
});
registerBlockStyle
とdomReady
を使用すると、DOMが完全に読み込まれたタイミングでのみスタイルバリエーションが登録されるようになります。詳しくは公式情報およびドキュメントをご覧ください。
Polaroid
スタイル選択により、自動で.is-style-polaroid
クラスがブロックのラッパーに追加されます。
次にスタイルバリエーションのCSSを追加します。/src/style.scss
を開き、以下のコードを追加してください。
.wp-block-image.is-style-polaroid {
padding: 15px 15px 70px 15px;
background-color: white;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
max-width: 360px;
transform: rotate(-3deg);
transition: transform 0.3s ease-in-out;
figure {
margin: 0 !important;
}
img {
display: block;
width: 100%;
height: auto;
}
figcaption {
position: absolute;
bottom: 15px;
left: 0;
right: 0;
text-align: center;
font-family: 'Permanent Marker', cursive;
color: #333;
font-size: 18px;
}
}
コードを保存してnpm run build
を実行し、WordPress管理画面に移動しましょう。新しい投稿またはページを作成し、画像を追加します。画像を選択した状態で、ブロックサイドバーの「スタイル」ラベルをクリックし、「Polaroid」を選択してください。

キャプションを追加して投稿を保存し、フロントエンドで結果を確認します。イタリック体のキャプションが付いたポラロイドスタイルの画像が表示されます。

ロジックの構築
次に、画像にアニメーション効果を加えるロジックを作成します。CSSのtransform
プロパティを使って簡単なアニメーションを実装します。まず、次のブロックをsrc/style.scss
に追加してみます。
.wp-block-image.is-style-polaroid.has-image-animation:hover {
transform: rotate(0deg) scale(1.05);
}
このコードにより、ブロックがポラロイド画像でありツールバーのトグルでhas-image-animation
クラスが付与されている場合にのみ、ホバー効果が適用されるようになります。
続いて、figure
要素である画像コンテナにCSSクラスを追加するロジックが必要です。そのために、いくつかのフィルターとコールバック関数を使います。
まず、src/index.js
ファイルに次の行を追加します。
import { addFilter } from '@wordpress/hooks';
ステップ1. 画像ブロックに新しい属性を追加する
コアの画像ブロックを操作するためにaddFilter
を使います。まず、画像ブロックに新しいimageAnimation
属性を追加します。
function addImageAnimationAttribute( settings, name ) {
if ( name !== 'core/image' ) {
return settings;
}
settings.attributes = {
...settings.attributes,
imageAnimation: {
type: 'boolean',
default: false,
},
};
return settings;
}
addFilter(
'blocks.registerBlockType',
'image-hacker/add-image-animation-attribute',
addImageAnimationAttribute
);
コールバック関数addImageAnimationAttribute
は2つの引数を取ります。
settings
– 現在のブロック属性の配列name
– 属性を変更したいブロックの名前を指定
その後、関数は更新された属性の配列を返します。
ステップ 2. 画像ブロックにトグルコントロールを追加する
次に、アニメーションを有効にするためのコントロールを画像ブロックのツールバーに追加します。
まず、index.js
ファイルに次のimport
を追加します。
import { createHigherOrderComponent } from '@wordpress/compose';
import { Fragment } from '@wordpress/element';
import { BlockControls } from '@wordpress/block-editor';
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
次に、次のコードをファイルの最後に追加します。
const withPolaroidControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
if (props.name !== 'core/image') {
return <BlockEdit {...props} />;
}
const { attributes, setAttributes, isSelected } = props;
const { imageAnimation, className, lightbox } = attributes;
return (
<Fragment>
<BlockEdit {...props} />
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon="format-image"
label={__('Toggle Animation', 'image-hacker')}
isActive={imageAnimation}
onClick={() =>
setAttributes({ imageAnimation: !imageAnimation })
}
/>
</ToolbarGroup>
</BlockControls>
</Fragment>
);
};
}, 'withPolaroidControls');
addFilter(
'editor.BlockEdit',
'image-hacker/with-polaroid-controls',
withPolaroidControls
);
このコードの実行内容は以下の通りです。
createHigherOrderComponent
関数はBlockEdit
をラップする高次コンポーネント(HOC)を作成- HOCはコンポーネントをインターセプトし、それが画像ブロックであるかどうかをチェック(これにより、すべての編集が画像ブロックにのみ適用される)
- デストラクチャリング代入を使用し、
props
、attributes
オブジェクトから必要なプロパティや属性を取り出す - その際
BlockControls
,ToolbarGroup
,ToolbarButton
コンポーネントを使用して、ブロックツールバーにアニメーションの切り替えボタンを追加 isActive
でデフォルト状態をimageAnimation
に設定onClick
でimageAnimation
の値をトグル

これで属性とボタンができました。しかし、ボタンをクリックしても何も起こりません。
ステップ3. ラッパー要素にCSSクラスを追加する
次に、画像をラップしているfigure
要素にhas-image-animation
クラスを適用します。これの実装のために、フロントエンドで画像にCSSクラスを割り当てるフィルターを使用します。
以下のコードをindex.js
ファイルに追加しましょう。
function addAnimationFrontendClass(extraProps, blockType, attributes) {
if (blockType.name === 'core/image' && attributes.imageAnimation) {
extraProps.className = `${extraProps.className || ''} has-image-animation`;
}
return extraProps;
}
addFilter(
'blocks.getSaveContent.extraProps',
'image-hacker/add-animation-frontend-class',
addAnimationFrontendClass
);
このコードにより、imageAnimation
属性がtrue
に設定されているとき、figure
要素に CSS クラスhas-image-animation
が追加されます。
これにより何が起こるのか、詳しく理解してみましょう。
addFilter
フックは、データや動作を変更するためにエディターのプロセスにフックするblocks.getSaveContent.extraProps
は対象としている特別なフック(extraProps
は、ラッパー要素に特別なHTML属性を追加できる特別なフック)image-hacker/add-animation-class
はフィルター固有の名前addAnimationFrontendClass
は、blocks.getSaveContent.extraProps
フックが実行されるたびに実行されるコールバック関数の名前(この関数は以下の3つの引数を取る)
-
extraProps
:className
のような、ブロックのラッパー要素のプロパティを含むオブジェクトblockType
:name
(core/image
) のようなブロックの詳細情報を保有するオブジェクトattributes
:ブロック属性のオブジェクト
- この関数のロジックでは、
blockType.name === 'core/image'
とattributes.imageAnimation
がtrue
のときのみコードが実行されるようになっている - 両方の条件が真の場合、関数は既存のクラスオブジェクトに
has-image-animation
を追加した新しいprops
オブジェクトを返す
では、実際に試してみます。コンテンツに画像を追加し、ブロックサイドバーからPolaroidスタイルを選択し、ブロックツールバーのToggle Animationボタンをクリックします。投稿を保存し、フロントエンドで結果を確認してください。画像にカーソルを合わせると、画像が回転するはずです。

ブロックバリエーションの登録
ブロックバリエーションは、複数の属性やネストされたブロックをあらかじめ設定したブロックのバージョンです。WordPressはこれを独立したブロックとして扱います。ブロックインサーターで選択し、カスタムアイコンを付けて表示できます。
ブロックバリエーションを使えば、デフォルトでポラロイドスタイルが適用された新しい画像ブロックを作成できます。
最初のステップとして、registerBlockVariation
関数を/src/index.js
ファイルにインポートします。
import { registerBlockStyle, registerBlockVariation } from '@wordpress/blocks';
次に、registerBlockStyle
のすぐ下、domReady()
の中にregisterBlockVariation
関数の呼び出しを追加します。
domReady(() => {
// 画像ブロックにスタイルバリエーションを登録
registerBlockStyle('core/image', {
name: 'polaroid',
label: 'Polaroid',
});
// 画像ブロックのブロックバリエーションを登録
registerBlockVariation('core/image', {
name: 'animated-polaroid',
title: 'Animated Polaroid',
icon: 'image-filter',
attributes: {
className: 'is-style-polaroid',
imageAnimation: true,
},
scope: ['inserter'],
});
});
registerBlockVariation
関数が既存のブロックのバリエーションを作成します。ブロックの名前と、バリエーションを定義するオブジェクトです。(ブロックバリエーション入門とブロックバリエーションAPI ドキュメントもご参照ください)
ファイルを保存し、ビルドを実行して変更を適用し、WordPress の管理画面に戻ります。新しい投稿を作成し、ブロックインサーターでAnimated Polaroidブロックを検索します。

テストとデバッグ
テストを行いましょう。新しい投稿に1つ以上の画像を追加し、それぞれにポラロイドスタイルを適用し、アニメーションを有効にしてリンクを設定します。さらに、Galleryブロックでも同様のテストを行います。
動作は概ね期待通りですが、ポラロイドスタイルの画像にライトボックス効果付きのリンクを設定しても、きれいな表示にはなりません。これは、WordPressのライトボックス機能とCSSトランジションの互換性による問題と考えられます。
長時間かかる複雑なデバッグを避けるため、クリック時に拡大するオプションを無効にし、ライトボックスが無効であることを知らせる警告を追加することをおすすめします。
まず、追加リソースをインポートします。以下は/src/index.js
ファイルでインポートするリソースの一覧です。
import { registerBlockStyle, registerBlockVariation } from '@wordpress/blocks';
import domReady from '@wordpress/dom-ready';
import { addFilter } from '@wordpress/hooks';
import { createHigherOrderComponent } from '@wordpress/compose';
import { Fragment, useEffect } from '@wordpress/element';
import { InspectorControls, BlockControls } from '@wordpress/block-editor';
import { PanelBody, Notice, ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useDispatch } from '@wordpress/data';
import './style.scss';
以下のインポートを追加しました。
useEffect
を@wordpress/element
からインポートInspectorControls
を@wordpress/block-editor
からインポート(ドキュメントを参照のこと)PanelBody
とNotice
を@wordpress/components
からインポート(docsを参照のこと)useDispatch
を@wordpress/data
からインポート(WordPress開発者ブログを参照のこと)
次に、withPolaroidControls
関数を以下のように変更します。
const withPolaroidControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
if (props.name !== 'core/image') {
return <BlockEdit {...props} />;
}
const { attributes, setAttributes, isSelected } = props;
const { imageAnimation, className, lightbox } = attributes;
const isPolaroid = className?.includes('is-style-polaroid');
const { createNotice } = useDispatch('core/notices');
useEffect(() => {
if (isPolaroid && lightbox?.enabled) {
// 競合を防ぐためにライトボックスを無効化
setAttributes({ lightbox: { ...lightbox, enabled: false } });
// 利用者に一時的な「スナックバー」通知を表示
createNotice(
'warning', // 通知の種類(info、success、warning、error)
__('Lightbox disabled for Polaroid style.', 'image-hacker'),
{
type: 'snackbar',
isDismissible: true,
}
);
}
}, [isPolaroid, lightbox]);
return (
<Fragment>
<BlockEdit {...props} />
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon="format-image"
label={__('Toggle Animation', 'image-hacker')}
isActive={imageAnimation}
onClick={() =>
setAttributes({ imageAnimation: !imageAnimation })
}
/>
</ToolbarGroup>
</BlockControls>
{isSelected && isPolaroid && (
<InspectorControls>
<PanelBody title={__('Polaroid Style', 'image-hacker')}>
<Notice status="info" isDismissible={false}>
{__(
'The "Expand on click" (lightbox) feature is disabled for this style to prevent visual conflicts.',
'image-hacker'
)}
</Notice>
</PanelBody>
</InspectorControls>
)}
</Fragment>
);
};
}, 'withPolaroidControls');
useEffect
はReact Hookで、コンポーネントを外部システムと同期させることができます。このコードは、コンポーネントがレンダリングされた後、依存配列[isPolaroid, lightbox]
の値が変更されるたびに実行されます。チェックが実行されるのは、ユーザーがPolaroidスタイルを適用または削除したとき、またはライトボックスを有効または無効にしたときだけです(Reactのドキュメントを参照のこと)。- 条件
if (isPolaroid() && lightbox.enabled)
により、画像に Polaroid スタイルがあり、lightbox オプションが有効になっている場合にのみコードが実行されます。 - 条件が
true
の場合、ライトボックスは無効になり、一時的な警告通知が表示されます(通知データリファレンスを参照のこと)。 - 条件
isSelected && isPolaroid
は、ライトボックスが無効であることをユーザーに通知するための新しいパネルを画像ブロックツールバーに生成します。スナックバーとは異なり、このパネルは永続的な警告を表示します。

まとめ
今回の記事では、WordPressブロックエディターの開発者向け機能の中でも、とくに実用性の高い要素を実際のプロジェクトを通してご紹介しました。
私たちはプログレッシブエンハンスメントの考え方に沿って、画像ブロックのブロックスタイルのバリエーションを作成しました。これにより、利用者は画像を手軽にクラシックなポラロイド風にできます。
続いて、画像ブロックのツールバーに専用ボタンを追加し、魅力的なホバーアニメーション効果を設定できるようにしました。
最後に、ポラロイドスタイルとアニメーション設定が標準で適用されるブロックバリエーションを用意し、全体をまとめました。
このチュートリアルで得た知見と手法を活用して、Gutenbergのコアブロックに驚くカスタマイズを加えてみてください。
それではコーディングにご活用ください。