GutenbergにプレーンなJSでカスタムブロックを追加する

カスタムブロックを追加する

カスタムブロックの作成に必要な最低限のファイルは次の通り。

  • block-slug.php: ブロックをPHP側に読み込ませる
  • block.json: JSとPHPどちらでも読み込めるブロック情報
  • index.js: ブロックを表示するためのロジック

style.cssでクライアント側の、index.cssでエディタ側のスタイルを指定できる(無論クライアント側はテーマのstyle.css中に記述してもOK、ただブロックのstyle.cssとして記述すると必要に応じて動的にCSSファイルを“読み込む/読み込まない”してくれる)。

これに加えダイナミックブロックの場合はrender.phpを用意することでクライアント側に表示するPHPを編集できる。

今回の要はJSX(wp-scripts buildによる自動生成)を利用しない方法であることから次のような手順で進める。

1. テーマフォルダ直下にblocks/フォルダを作成(Optional)

この中にカスタムブロックのフォルダを入れることで整理整頓できる。

2. blocks/フォルダ内にブロックフォルダを作成(Recommend)

ここではblock-pizza/を作成。このフォルダ内にPizzaブロックに必要なファイルたちを用意する。

3. block.jsonでブロックのメタデータを記述(Must)

{
  "$schema": "https://schemas.wp.org/trunk/block.json",
  "apiVersion": 2,
  "name": "my-category/block-pizza",
  "title": "ピッツァ",
  "description": "ピッツァカスタムブロックを追加します。",
  "icon": "format-status",
  "category": "text",
  "attributes": {
    "pizzaText": {
      "type": "string",
      "source": "html",
      "selector": "p"
    }
  },
  "example": {
    "innerBlocks": [
      {
        "name": "my-category/block-pizza",
        "attributes": "おいしいピッツァ"
      }
    ]
  }
}

編集できる箇所は次の通り(*は必須項目)。

  • name*: オリジナルのネームスペースとブロックのスラッグ名をスラッシュ区切りで記入すると良い
  • title*: エディタに表示される。カスタムブロックの名前。
  • description: エディタに表示される。カスタムブロックの説明文。
  • icon: エディタに表示される。カスタムブロックのアイコン(dashicon)。
  • category: カスタムブロックのカテゴリ。
  • attributes: カスタムブロックの属性。
  • example: エディタに表示される。使用例の小窓に表示するコンテンツ。

https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/

ダイナミックブロックを作る場合は次をJSONに追記

  ...
  "render": "file:./render.php"
  ...

これで同フォルダ内のrender.phpファイルを指定できる。

4. index.jsを用意する

( function ( wp ) {

  var el = wp.element.createElement;
  var registerBlockType = wp.blocks.registerBlockType;
  var useBlockProps = wp.blockEditor.useBlockProps;
  var richText = wp.blockEditor.RichText;

  registerBlockType( 'my-category/block-pizza', {

    edit: function ( props ) {
      return el(
        richText,
        Object.assign( useBlockProps(), {
          tagName: 'p',
          value: props.attributes.pizzaText,
          allowedFormats: [
            'core/bold',
            'core/italic',
            'core/link',
          ],
          onChange: function ( content ) {
            props.setAttributes( { content: content } );
          },
          placeholder: 'おいしいピッツァ',
        } )
      );
    },

    save: function ( props ) {
      return el(
        richText.Content,
        Object.assign( useBlockProps.save(), {
          tagName: 'p',
          value: props.attributes.pizzaText,
        } )
      );
    },

  } );
}(
  window.wp
) );

registerBlockType()函数の第一引数とblock.jsonのname値が同一であることを確認(でないとエラーが出る)。

見るべきはeditsave。他はテンプレートだと思って問題ない。editでエディタの表示や編集ツールバーのあれこれを設定できる。saveでクライアント側に表示させるHTMLのあれこれを調整できる。

el()はReactのcreateElement()とほぼ同じ(https://beta.reactjs.org/reference/react/createElement)。そのためrichTextとなっている箇所を'p'や'div'などHTML要素名にしても良い。ここではrichTextとすることで太字や斜体、リンクづけなどのツールバーを表示させるようにしている(https://developer.wordpress.org/block-editor/reference-guides/richtext/)

ダイナミックブロックの場合は次のように書くことが出来る。

( function ( wp ) {

  var registerBlockType = wp.blocks.registerBlockType;
  var el = wp.element.createElement;
  var useBlockProps = wp.blockEditor.useBlockProps;

  registerBlockType( 'my-category/block-pizza', {
    edit: function () {
      return el(
        'p',
        useBlockProps(),
        'Pizza Block – hello from the editor!',
      );
    },
  } );
}(
  window.wp
) );

5. block-pizza.phpを用意する

用意してきたファイルたちをWordPressに読み込ませるために、新たなファイルを作成する。

結論としてはwp_register_script()register_block_type()init時に読み込ませられれば良いのだが、折角なのでファイルも綺麗にオーガナイズ(整理整頓)してみよう。

<?php
function pizza_block_init() {
  wp_register_script(
    'pizza-block-editor',
    get_theme_file_uri( 'blocks/block-pizza/index.js' ),
    array(
      'wp-block-editor',
      'wp-blocks',
      'wp-element',
    ),
    filemtime( __DIR__ . '/index.js' )
  );

  register_block_type(
    __DIR__,
    array(
      'editor_script_handles' => array(
        'pizza-block-editor',
      ),
    )
  );
}
add_action( 'init', 'pizza_block_init' );

これをfunctions.phprequire_onceしてやれば読み込まれる。

...
// pizzaカスタムブロックの追加
require_once get_theme_file_path( 'blocks/block-pizza/block-pizza.php' );
...

ダイナミックブロックの場合は次のようなrender.phpファイルを用意する。

<p <?php echo get_block_wrapper_attributes(); ?>>
    <?php echo esc_html( 'Pizza Block – hello from a dynamic block!' ); ?>
</p>

これがクライアント側に出力される。

6. CSSファイルを追加する

スタイルは大切です。エディタ側のCSSを追記しましょう。

index.cssをブロックフォルダ内に作成します。

.wp-block-my-category-block-pizza {
  border: 1px solid magenta;
}

block-pizza.phpを次のように編集して完了です。

function pizza_block_init() {
  wp_register_script(
    'pizza-block-editor',
    get_theme_file_uri( 'blocks/block-pizza/index.js' ),
    array(
      'wp-block-editor',
      'wp-blocks',
      'wp-element',
    ),
    filemtime( __DIR__ . '/index.js' )
  );

  wp_register_style(
    'pizza-block-editor-style',
    get_theme_file_uri( 'blocks/block-pizza/index.css' ),
    array(),
    filemtime( __DIR__ . '/index.css' )
  );

  register_block_type(
    __DIR__,
    array(
      'editor_script_handles' => array(
        'pizza-block-editor',
      ),
      'editor_style_handles' => array(
        'pizza-block-editor-style',
      ),
    )
  );
}
add_action( 'init', 'pizza_block_init' );

この記事は2023年2月にまとめた個人的な資料です。公開時含め現在のWordPressバージョンではテストしていません。ご了承を…。

8102419787013034471 https://www.storange.jp/2023/12/add-custom-block-to-gutenberg-without-using-wp-scripts.html https://www.storange.jp/2023/12/add-custom-block-to-gutenberg-without-using-wp-scripts.html GutenbergにプレーンなJSでカスタムブロックを追加する 2023-12-26T11:57:00+09:00 https://www.storange.jp/2023/12/add-custom-block-to-gutenberg-without-using-wp-scripts.html Hideyuki Tabata 200 200 72 72