WP-CLI を使用したブロックの生成

静的なコンテツを含む可能な限りシンプルなブロックを書こうとしても、これは簡単な作業ではありません。ドキュメントに書かれた手順を1つずつ追いかけ、少なくとも2つのファイルを作成し、コードを既存の API と統合する必要があります。この面倒さを解消する1つの方法は動作可能なサンプルを含むレポジトリーから既存ブロックのソースコードをコピーする方法です。

すべてのコアブロックのフォルダーを参照し実装を調べるのも良い考えです。

WP-CLI

もう1つの開発者をラクにしてくれる方法が WP-CLI です。WP-CLI は WordPress に対する多くの操作をコマンドラインから実行できますが、その中にプラグインやテーマ用の Gutenberg ブロック登録に必要なすべてのコードを生成するコマンドがあります。

インストール

WP-CLI をインストールする前に使用環境が必要最低要件を満たしていることを確認してください。

  • UNIX 互換環境 (macOS、Linux、FreeBSD、Cygwin)。Windows 環境は限定的なサポートです。
  • PHP 5.3.29 以上
  • WordPress 3.7 以上

確認を終えたら、インストール手順に従ってください。大部分のユーザーには Phar ファイルのダウンロードによるインストール方法を推奨します。必要に応じて代替のインストール方法のドキュメントも参照してください。

wp scaffold block の使用

次のコマンドを実行するとブロックを登録する PHP、JS、CSS コードを生成します。

wp scaffold block <slug> [--title=<title>] [--dashicon=<dashicon>] [--category=<category>] [--theme] [--plugin=<plugin>] [--force]

ブロックで利用可能なその他のオプションについてはコマンドのドキュメントを参照してください。

ブロックのひな形を作成する際には少なくとも slug 名と theme 名または plugin 名のどちらかを指定する必要があります。多くの場合はブロックはテーマでなくプラグインとペアにすることを推奨します。プラグインを使用していればテーマを変更されてもすべてのブロックは稼働します。

サンプル

wp scaffold block の使用例をいくつか挙げます。

プラグイン内部でのブロックの作成

次のコマンドを実行すると、既存のプラグイン movies に対してタイトル My movie block のブロック movie を生成します。

$ wp scaffold block movie --title="My movie block" --plugin=movies
Success: Created block 'My movie block'.

コマンドは movies プラグインディレクトリに4つのファイルを生成します。すべてのファイルにはインラインドキュメントがあり、ブロックをカスタマイズする際のガイドとなります。なお現在の仕様として、静的コンテンツを含むブロックのひな形のみを生成できます。また JavaScript コードはすべてのモダンなブラウザーで動作可能な ECMAScript 5 (ES5) 標準で書かれています。

訳注: WP-CLI の出力するコメントは英語ですが、わかりやすさのため翻訳しました。また URL も日本語版があるものについては置換しました。

movies/blocks/movie.php – メインのプラグインファイルに手動でこのファイルを含める必要があります。

<?php
/**
 * Gutenberg ブロック用にクライアントサイドのアセット (スクリプトとスタイル) を登録する関数
 * 
 * @package movies
 */

/**
 * ブロックのすべてのアセットを登録し、Gutenberg を介して対応するコンテキスト内に
 * エンキューできるようにする
 *
 * @see https://ja.wordpress.org/team/handbook/block-editor/tutorials/block-tutorial/writing-your-first-block-type/
 */
function movie_block_init() {
    $dir = dirname( __FILE__ );

    $block_js = 'movie/block.js';
    wp_register_script(
        'movie-block-editor',
        plugins_url( $block_js, __FILE__ ),
        array(
            'wp-blocks',
            'wp-i18n',
            'wp-element',
        ),
        filemtime( "$dir/$block_js" )
    );

    $editor_css = 'movie/editor.css';
    wp_register_style(
        'movie-block-editor',
        plugins_url( $editor_css, __FILE__ ),
        array(),
        filemtime( "$dir/$editor_css" )
    );

    $style_css = 'movie/style.css';
    wp_register_style(
        'movie-block',
        plugins_url( $style_css, __FILE__ ),
        array(),
        filemtime( "$dir/$style_css" )
    );

    register_block_type( 'movies/movie', array(
        'editor_script' => 'movie-block-editor',
        'editor_style'  => 'movie-block-editor',
        'style'         => 'movie-block',
    ) );
}
add_action( 'init', 'movie_block_init' );

movies/blocks/movie/block.js:

( function( wp ) {
    /**
     * 新しいブロックを登録。他と衝突しないユニークな名前、動作を定義するオブジェクトを指定する。
     * @see https://developer.wordpress.org/block-editor/developers/block-api/block-registration/
     */
    var registerBlockType = wp.blocks.registerBlockType;
    /**
     * 指定したタイプの新しい要素を返す。要素は React の上の抽象化レイヤー
     * @see https://developer.wordpress.org/block-editor/packages/packages-element/
     */
    var el = wp.element.createElement;
    /**
     * テキストの翻訳を取得
     * @see https://developer.wordpress.org/block-editor/packages/packages-i18n/
     */
    var __ = wp.i18n.__;

    /**
     * すべてのブロックは新しいブロックタイプの定義を登録するところから始める
     * @see https://developer.wordpress.org/block-editor/developers/block-api/block-registration/
     */
    registerBlockType( 'movies/movie', {
        /**
         * ブロックの表示名。`i18n` 関数で翻訳できる。
         * ブロックインサーターはこの名前を表示
         */
        title: __( 'My movie block' ),

        /**
         * ユーザーが見つけやすいよう、ブロックはカテゴリーにグループ分けされる。
         * コアで提供するカテゴリーは `common`(一般ブロック)、`embed`(埋め込み)、
         * `formatting`(フォーマット)、`layout`(レイアウト要素)、`widgets`(ウィジェット)
         */
        category: 'widgets',

        /**
         * オプションのブロック拡張サポート機能
         */
        supports: {
            // HTML モードサポートの削除
            html: false,
        },

        /**
         * edit 関数はエディターのコンテキストにおけるブロックの構造を記述する。
         * ブロックが使用された際に、エディターが何をレンダリングするかを表す。
         * @see https://developer.wordpress.org/block-editor/developers/block-api/block-edit-save/
         *
         * @param {Object} [props] エディターから渡されるプロパティ
         * @return {Element}       レンダリングする要素
         */
        edit: function( props ) {
            return el(
                'p',
                { className: props.className },
                __( 'Hello from the editor!' )
            );
        },

        /**
         * save 関数は異なる属性が最終的なマークアップにどのように組み合わせられるかを定義する。
         * マークアップは Gutenberg により `post_content` にシリアライズされる。
         * @see https://developer.wordpress.org/block-editor/developers/block-api/block-edit-save/#save
         *
         * @return {Element}       レンダリングする要素
         */
        save: function() {
            return el(
                'p',
                {},
                __( 'Hello from the saved content!' )
            );
        }
    } );
} )(
    window.wp
);

movies/blocks/movie/editor.css:

/**
 * エディター内でのみ適用されるスタイル
 *
 * 以下のスタイルを置換するか、このファイル自体を削除する
 */

.wp-block-movies-movie {
    border: 1px dotted #f00;
}

movies/blocks/movie/style.css:

/**
 * サイトのフロントエンド、またはエディターの両方に適用されるスタイル
 *
 * 以下のスタイルを置換するか、このファイル自体を削除する
 */

.wp-block-movies-movie {
    background-color: #000;
    color: #fff;
    padding: 2px;
}

テーマ内部のブロックの作成

同じ movie ブロックのひな形を既存のテーマに対しても生成できます。simple-life テーマの場合、

$ wp scaffold block movie --theme=simple-life
 Success: Created block 'Movie block'.

プラグインと2つのブロックの作成

プラグインが存在しなければ新規に作成し、2つのブロックを生成することもできます。

# プラグイン books の作成
$ wp scaffold plugin books

# プラグイン books にブロック book を追加
$ wp scaffold block book --title="Book" --plugin=books

# プラグイン books に2番目のブロックを追加
$ wp scaffold block books --title="Book List" --plugin=books