@wordpress/scriptsでオリジナルブロック作成

@wordpress/scriptsとは

WordPress開発のためのNode.jsベースのビルドツールキットで、ビルドプロセスを簡素化することができます。

開発プロセスの3要素 ビルド (webpack) • モジュールのバンドル • コード最適化 コンパイル (Babel) • ES6+ → ES5変換 • ブラウザ互換性確保 リント (ESLint) • コード品質チェック • エラー検出

Babel:
Babelは、最新のJavaScript(ES6+)を古いブラウザでも動作する形に変換します

webpack:
webpackは、JavaScriptアプリケーションのための静的モジュールバンドラーです。複数のJavaScriptファイルを1つにまとめ複数のJavaScriptファイルを1つにまとめ、コードを最適化し、アプリケーションの読み込み速度を向上させます。

開発ワークフロー: Babel, webpack, ESLint 開発者のコード (ES6+, JSX等) ESLint Babel webpack 最終的な ブラウザ互換コード

手順

npm プロジェクトの初期化

package.json ファイルを作成します。

npm init -y

@wordpress/scriptsのインストール

(WordPress のブロックエディター用のパッケージ)

npm install @wordpress/scripts @wordpress/blocks @wordpress/i18n @wordpress/block-editor @wordpress/components @wordpress/data react react-dom

package.jsonにスクリプトが追記されます

{
  "name": "my-theme-custom-block",
  "version": "1.0.0",
  "description": "My first WordPress custom block in a theme",
  "main": "build/index.js",
  "scripts": {
    "build": "wp-scripts build",
    "start": "wp-scripts start"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@wordpress/scripts": "^x.x.x"
  }
}

ソースファイルファイル作成

wp-content

 ┣ themes

    ┣ custometheme(独自WPテーマ)

       ┣ src 

          ┣ blocks(独自ブロックのソースフォルダを追加していく)

             ┣ sample(独自ブロックのソースフォルダ)

                ┗ index.js
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';

registerBlockType('customtheme/simple01', {
    title: 'sample01',
    icon: 'smiley',
    category: 'text',
    edit: function() {

        // ブロックの属性を設定
        const blockProps = useBlockProps({
            className: 'my-custom-class',
            style: {
                backgroundColor: 'lightgrey',
                padding: '20px',
            }
        });

        return (
            <div { ...blockProps }>
                sample01 (エディター内)
            </div>
        );
    },
    save: function() {
        const blockProps = useBlockProps.save({
            className: 'my-custom-class',
            style: {
                backgroundColor: 'lightgrey',
                padding: '20px',
            }
        });
        return (
            <div { ...blockProps }>
                sample01 (フロントエンド)
            </div>
        );
    },
});
WordPress Custom Block: customtheme/simple01 WordPressカスタムブロック: customtheme/simple01 Edit Function (編集機能) useBlockProps({ className: ‘my-custom-class’, style: { backgroundColor: ‘lightgrey’, padding: ’20px’, } }); sample01 (エディター内) 説明: エディター内でのブロックの外観と動作を定義します。 useBlockPropsを使用してクラス名やスタイルを設定しています。 ここでの変更はエディター画面にのみ影響します。 Save Function (保存機能) useBlockProps.save({ className: ‘my-custom-class’, style: { backgroundColor: ‘lightgrey’, padding: ’20px’, } }); sample01 (フロントエンド) 説明: フロントエンドでのブロックの表示を定義します。 useBlockProps.saveを使用してクラス名やスタイルを設定しています。 ここでの設定が実際のウェブサイト上での表示に反映されます。

useBlockProps

Gutenbergエディタとの互換性が保証されるので使用推奨です

editsaveでの違い:

  • editではuseBlockProps()を使用:エディタ内での表示と操作に必要な属性を追加します。
  • saveではuseBlockProps.save()を使用:フロントエンドでの表示に必要な属性のみを追加します。
useBlockPropsの使用例 使用例1: 基本的な使用 const MyBlock = () => { const blockProps = useBlockProps(); return ( <div {…blockProps}> ブロックの内容 </div> ); }; 使用例2: カスタムクラスとスタイル const MyBlock = () => { const blockProps = useBlockProps({ className: ‘my-custom-class’, style: { color: ‘blue’ } }); return <div {…blockProps}>内容</div>; }; 使用例3: save関数での使用 const MyBlock = { // … other properties … save: () => { const blockProps = useBlockProps.save(); return ( <div {…blockProps}> 保存された内容 </div> ); } }; 非使用例: 推奨されない方法 const MyBlock = () => { return ( <div className=”wp-block”> ブロックの内容 </div> ); }; 注: 必要な属性が欠落し、将来の互換性が 保証されません。Gutenbergエディタとの 完全な互換性も失われる可能性があります。

webpack.config.jsでビルドについての設定を記述

プロジェクトのルートに webpack.config.js を作成しカスタマイズ内容を記述

const defaultConfig = require('@wordpress/scripts/config/webpack.config');
const path = require('path');

module.exports = {
    ...defaultConfig,

    // エントリーポイントの設定
    entry: {
        sample01: path.resolve(__dirname, 'wp-content/themes/customtheme/src/blocks/sample01/index.js'),
    },

    // 出力の設定
    output: {
        path: path.resolve(__dirname, 'wp-content/themes/customtheme/build'),
        filename: '[name].js', // [name] には entry で指定したキーが入る
    },
};

functions.php編集

// カスタムブロックの登録
function my_theme_custom_block_init() {

  // register_block_type()の第一引数は「ドメイン名/ブロック名」でregisterBlockType()の第一引数と一致させる
  register_block_type( 'custom-theme/simple01', array(
    'editor_script' => 'sample01-block-script',
  ) );
}
add_action( 'init', 'my_theme_custom_block_init' );

// ブロックのスクリプトを読み込む
function my_theme_custom_block_enqueue_assets() {
  $asset_file_sample01 = include( get_template_directory() . '/build/sample01.asset.php' );

  wp_enqueue_script(
      'sample01-block-script',
      get_template_directory_uri() . '/build/sample01.js',
      $asset_file_sample01['dependencies'],
      $asset_file_sample01['version']
  );
}
add_action( 'enqueue_block_editor_assets', 'my_theme_custom_block_enqueue_assets' );

ビルドの実行

以下のコマンドを実行して、ソースコードをビルドします。

npm run build
webpackビルドプロセス エントリーポイント sample01/index.js webpack処理 モジュールのバンドル コードの変換・最適化 出力 build/sample01.js webpack.config.js ソースファイル: customtheme/src/blocks/ sample01/index.js 出力先: customtheme/build/ sample01.js

ビルドする理由

  • import文は ES6 モジュール構文です。多くの最新のブラウザはこれをサポートしていますが、WordPressの管理画面で使用される可能性のある古いブラウザでは問題が発生する可能性があります。
  • @wordpress/blocks のようなパッケージは、npm(Node Package Manager)を通じてインストールされます。ブラウザはnpmの構造を直接理解できません。
  • ReactのJSX構文で、標準のJavaScriptではありません。ブラウザはこれを直接解釈できません。
    • JSXを使用する場合、一般的には拡張子を変更することが推奨されていますが、WordPress のブロック開発においては必ずしもそうではありません。@wordpress/scripts(WordPress 公式の開発ツール)は、デフォルトで .js ファイルも JSX として処理します。

Attributes Object
TextControl (@wordpress/components) の使用例

テキスト入力フィールドを作成するためのコンポーネントです。

import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import { TextControl } from '@wordpress/components';
import { useState } from '@wordpress/element';

registerBlockType('customtheme/sample02', {
    title: 'テキスト入力ブロック',
    icon: 'edit',
    category: 'text',
    attributes: {
        content: {
            type: 'string',
            default: '',
        },
    },
    edit: function Edit({ attributes, setAttributes }) {
        const [text, setText] = useState(attributes.content);

        const blockProps = useBlockProps({
            className: 'my-text-input-block',
            style: {
                backgroundColor: 'lightgrey',
                padding: '20px',
            }
        });

        const onChangeContent = (newContent) => {
            setText(newContent);
            setAttributes({ content: newContent });
        };

        return (
            <div { ...blockProps }>
                <TextControl
                    label="テキストを入力"
                    value={text}
                    onChange={onChangeContent}
                    placeholder="ここにテキストを入力してください"
                />
                <p>入力されたテキスト: {text}</p>
            </div>
        );
    },
    save: function Save({ attributes }) {
        const blockProps = useBlockProps.save();
        return (
            <div { ...blockProps }>
                <p>{attributes.content}</p>
            </div>
        );
    },
});
WordPress Block Attributes Object attributes オブジェクト content type: ‘string’ source: ‘html’ selector: ‘p’ default: ” alignment type: ‘string’ default: ‘none’ backgroundColor type: ‘string’ default: ‘#ffffff’ Block Editor ユーザーが編集 setAttributes() で更新 Frontend Display 保存された attributes を使用 HTML として出力

参考サイト

[Gutenberg]オリジナルブロックの制作方法まとめ
https://sushirice.pro/create-theme/1532/