WordPressブロック開発の始め方 2024年5月版

自身の勉強のため、データをまとめている最中の書きかけのページです。Wordpressのブロック開発の始め方を自分の為にまとめています。以下の記事を参考に自分なりに再構築しています。なので、最初は著作権と年を表示するブロックの開発をハンズオンで行いながら説明します。

事前準備

ブロック開発に必要な事前知識は、HTMLとCSSはもちろん、PHPとWordpressテンプレートタグ、Javascriptなどの今までと同じWordpressの開発知識に加え、Javascriptも必要となりました。また、開発にはPHP&MySQLのWordpress動作環境の他に、Node.jsが必要となります。

準備 – Node.js

開発にはJavascriptをサーバサイドで動かす必要があるため、Node.jsを導入します。以下のURLよりダウンロードし、インストールをして準備します。
https://nodejs.org/en/download/

準備 – コードエディタ

コードエディタは、ソースが編集できれば何でも良いです。お気に入りのエディタを使います。以下のURLは、私が使っているエディタです。
https://azure.microsoft.com/ja-jp/products/visual-studio-code

準備 – ローカル環境

WordPressを動かすには、WebサーバとPHP、MySQL(MariaDB)が動く環境が必要です。いろいろな方法がありますが、いくつかのインストーラーをリストアップしておきます。
Windows – https://www.apachefriends.org/jp/download.html
Mac – https://www.mamp.info/en/downloads/
Linux – https://varyingvagrantvagrants.org/
共通 – Dockerで環境を作ってしまう

準備 – WordPress

ローカル環境にWordpressをインストールしておきます。Wordpressの本体ファイルは以下にあります。Xamppなどのローカル環境のhtdocsなどのフォルダ内へ解凍したものを配置し、事前インストールしてください。
https://ja.wordpress.org/download/

pluginsフォルダに
ブロック追加の種を作る

コマンドプロントなどのコマンドツールを開き、pluginsディレクトリへ移動します。以下は、xamppの場合の例です。cdはディレクトリを移動するコマンド。../は一つ上に移動するコマンド。

cd ../../
cd xampp/htdocs/wordpress/wp-content/plugins/

pluginsフォルダへ移動したら、どのようなプラグインを作るのかファイル名を考えます。今回は、test-blockという名前のブロックを作ります。以下のコマンドを入力し、ブロック追加プラグインの種を作ります。

npx @wordpress/create-block@latest test-block --variant=dynamic

Ok to proceed? (y)などとでたら、yを入力してエンターキーを押してください。種のインストールが始まります。インストールは数分かかります。インストールが終わったら次へ。pluginsディレクトリに、開発用のtest-blockディレクトリと管理画面のプラグインにTest Blockが出来ました。

生成したプラグインの有効化

生成されたプラグインを有効化しておきます。有効化することで、今回生成したブロックの種がブロックリストに表示されます。

開発用プラグインGutenbergの導入

開発用のプラグインGutenbergを導入します。
WPダッシュボード→プラグイン→新規プラグインを追加
 →「Gutenberg」と検索→今すぐインストール→有効化

(※未確定事項 Gutenbergを有効化したまま作成した際、適切にインストールがされなかった自体が発生。念の為、ブロック追加の種を作成する前には、Gutenbergを停止しておいたほうが良いかもしれない。)

開発用プラグインCreate Block Themeの導入

必須ではありませんが、ついでにテーマ作成時に使用するプラグイン「Create Block Theme」もインストールしておきます。
WPダッシュボード→プラグイン→新規プラグインを追加
 →「Create Block Theme」と検索→今すぐインストール→有効化

開発前に必ずやること

ディレクトリの移動

コマンドのpathを開発するプラグインディレクトリに合わせておく必要があります。今回の場合は、test-blockディレクトリに合わせます。上から順に作業をしている場合は、以下のコマンドを入力します。

cd test-block

また、新しくコマンドツールを立ち上げた際は、以下のコマンドになります。
以下は、xamppの場合の例なので、環境に合わせて調整してください。

cd ../../
cd xampp/htdocs/wordpress/wp-content/plugins/test-block/

自動コンパイルモードの開始

コードの書き換えなどが完了した際、以下のコマンドを入力することで、コンパイルを自動で行うようにします。時々、この状態が勝手に解除されますので、解除されていたら開始してください。この状態を解除するには、Ctrl+Cキーで出来ます。

npm start

WordPressのバージョン(言語も関係?)によって、エラーが起きる場合があります。

WP管理画面で表示させる

WordPressダッシュボード→外観→エディターの順に選択
 →パターン→フッターを選択
  →footerの右横にあるペンのアイコンを選択
   →右の白い画面を選択して編集を開始します。

上部左側にある3本線のバーガーメニューをクリックしてリストを表示させます。

  1. リスト表示の「グループ」右横にある三点メニューをクリックして削除を選択
  2. 「グループ」が「段落」に変更されていることを確認
  3. 上部左側にあるプラスアイコンを選択し、Test Blockを選択
  4. リスト表示のTest Block右横にある三点メニューをクリックしてグループ化を選択
  5. 右上の保存を選択→保存を確定させます

WPフロント画面でフッター部分を表示させる

ブラウザの別タブで、ダッシュボードからホームアイコンを選択し、トップページを表示。画面下部のフッター部分を表示しておきます。

ブロック開発 基本

最初は、管理画面側を設定していきます。ここはJavascriptの基本的なプログラミングが必要となります。test-block/srcディレクトリにあるデータを主に編集しますのでフォルダを開いておいてください。また、前述のコードエディタも使用しますので準備をしてください。今回は、Wordpress公式のブロック作成チュートリアルに沿った内容で解説します。

今回作るもの

フッターなどによくある、年と著作権表示をするブロックを作成します。

block.jsonの設定

まず最初に、ブロックエディタの初期設定を行ったり、編集用のツール類を組み込みます。test-block/src/block.jsonをエディタで開きます。

block.jsonの役割は、以下のようなものとなります。詳しくは、こちらのページを参考にしてください。

  • ブロックの基本的なメタデータ
  • ブロックの動作、スタイル、出力のためのファイル
  • ブロック内へのデータ保管
  • ブロックの UI パネルの設定

今回は、編集に必要な最小限の機能を搭載しますので、事前に以下の行をそれぞれ変更と追加、削除をしてください。なお、デフォルトのアイコンを利用する際は、ここを参考にしてください。

▼以下のプロパティの行の内容をそれぞれ変更 ※この行は含めない
"description": "サイトの著作権と公開年を表示",
"category": "text",

▼サポートに、色とタイポグラフィを追加
"supports": {
	"color": {
		"background": false,
		"text": true
	},
	"typography": {
		"fontSize": true,
		"lineHeight": true,
		"textAlign": true
	},
	"html": false
},

▼下記の各プロパティ行をそれぞれ削除
"icon":~
"editorStyle":~
"style":~
"viewScript":~

※カンマ(,)が一番の行にあったら削除

書き換えたら保存をし、Wordpress管理画面のfooterブロック編集画面を再読込します。情報が変わり、ツール類が増えていることを確認してください。

WordPressフロント画面側のフッターも変更されています。

index.jsに直接icon用のSVG画像を埋め込む

test-block/src/index.jsをエディターで開きます。index.jsはblock.jsonを受け取るプログラムです。アイコンとして規定サイズの24x24pxで作成したSVG画像のソースコードを直接埋め込みます。

//import metadata from './block.json';の下に以下を挿入
const calendarIcon = (
    <svg
        viewBox="0 0 24 24"
        xmlns="http://www.w3.org/2000/svg"
        aria-hidden="true"
        focusable="false"
    >
        <path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm.5 16c0 .3-.2.5-.5.5H5c-.3 0-.5-.2-.5-.5V7h15v12zM9 10H7v2h2v-2zm0 4H7v2h2v-2zm4-4h-2v2h2v-2zm4 0h-2v2h2v-2zm-4 4h-2v2h2v-2zm4 0h-2v2h2v-2z"></path>
    </svg>
);

//iconプロパティを追加 
registerBlockType( metadata.name, {
    icon: calendarIcon,
    edit: Edit
} );

管理画面を再読込すれば、Test Blockのブロックアイコンが変更されます。

edit.jsで、管理画面上のブロックを編集

test-block/src/edit.jsをエディターで開きます。edit.jsは、管理画面上のブロックの機能と表示を編集できます。Edit()関数を編集します。

export default function Edit() {
    const currentYear = new Date().getFullYear().toString();
    return (
        <p { ...useBlockProps() }>© { currentYear } YourSiteName.</p>
    );
}

管理画面を再読込みしてブロックを確認しましょう。

render.phpで、フロント画面の表示を編集

test-block/src/render.phpをエディターで開きます。render.phpで、フロント画面のブロックの表示をコントロールできます。Edit()関数を編集します。ここでは、Wordpressのテンプレートタグも利用できます。

<p <?php echo get_block_wrapper_attributes(); ?>>
	<small>© <?php echo date( "Y" );?> <?php bloginfo('name');?>.</small>
</p>

利用しない機能を外す

利用しない機能を外して、シンプルにします。

編集 src/edit.js

下記の行をコメントアウト
// import './editor.scss';

編集 src/index.js

下記の行をコメントアウト
// import './style.scss';

ここまでをビルドします

ビルドの前に、コマンドツールで今動いているnpm startを止めます。コマンドツールでnpm startが動いている画面を開き、Ctrlキーを押しながらCキーを押し、y→エンターでパッチジョブを終了します。
ここで、次のコマンド入力をし、ビルドします。

npm run build

ブロック開発 フォームの利用

ここからは、より実用的なカスタマイズの方法です。上記で作成したテストブロックを元にして、下記の機能を実装していきます。

  • 管理画面->ブロック 公開年表示有無のチェックボックス追加
  • 管理画面->ブロック 公開年の入力フォーム追加
  • フロント->ページフッター 公開年表示

block.jsonにプロパティと型定義を設定

block.jsonに利用する任意プロパティと型の定義を設定します。”example”:~の行の下に、以下のコードを追加します。公開年有無表示のチェックボックスは、showStartingYearでブーリアン型。公開年の文字列は、startingYearで文字型にします。

"example": {},
"attributes": {
	"showStartingYear": {
		"type": "boolean"
	},
	"startingYear": {
		"type": "string"
	}
},

edit.jsにフォームの機能を追加

  • 機能のオンオフを切り替えられるユーザーインターフェース
  • ユーザーが開始年を入力出来るユーザーインターフェース

独自のカスタムパネルを作成出来るようにする

edit.jsにInspectorControlsコンポーネントを設定することで、カスタムパネルを設置できます。

下記の行に、InspectorControlsを追加します。
import { useBlockProps } from '@wordpress/block-editor';
↓
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';

また、返り値の箇所をJSX構文にするため<>~</>で囲み、ブロック編集を差し込む<InspectorControls></InspectorControls>も追加します。

export default function Edit() {
    const currentYear = new Date().getFullYear().toString();
    return (
        <>
            <InspectorControls>
                Testing
            </InspectorControls>
            <p { ...useBlockProps() }>© { currentYear } YourSiteName.</p>
        </>
    );
}

保存をし、管理画面のブロック設定にTestingという文字列が表示されます。

さらに、いくつかのコンポーネントを導入します。インポート部分に、以下のソースコードを追加してコンポーネントを追加します。コンポーネント一覧は、こちらの公式ドキュメントが詳しいです。

import { PanelBody, TextControl, ToggleControl } from '@wordpress/components';

先ほど追加したInspectorControlsの中に、フォームを仕分けするためのパネルを追加します。パネルの詳細は、こちらの公式ドキュメントを参考にします。

            <InspectorControls>
                <PanelBody title={ __( 'Settings', 'test-block' ) }>
                    Testing
                </PanelBody>
            </InspectorControls>

管理画面ブロック設定のブラウザを再読込すると、このようにパネルの中に入ります。

エディタに各フォームを設定する

まずは、block.jsonに型設定したプロパティ(showStartingYearとstartingYear)をedit.jsに設定します。Edit()関数に引数を差し込み。各定数を設定します。

export default function Edit( { attributes, setAttributes } ) {
    //console.log(attributes);
    const { showStartingYear, startingYear } = attributes;
    const currentYear = new Date().getFullYear().toString();

次に、textボックスを設置するため、下記のコードをTesting文字列の箇所と差し替えます。

            <InspectorControls>
                <PanelBody title={ __( 'Settings', 'test-block' ) }>
                    <TextControl
                        label={ __(
                            'Starting year',
                            'test-block'
                        ) }
                        value={ startingYear || '' }
                        onChange={ ( value ) =>
                            setAttributes( { startingYear: value } )
                        }
                    />
                </PanelBody>
            </InspectorControls>

さらに、ON/OFFのためのtoggleコントロール(チェックボックス)を設置します。また、ON時にのみtextボックスが表示されるようにします。

            <InspectorControls>
                <PanelBody title={ __( 'Settings', 'test-block' ) }>
                    <ToggleControl
                        checked={ !! showStartingYear }
                        label={ __(
                            'Show starting year',
                            'test-block'
                        ) }
                        onChange={ () =>
                            setAttributes( {
                                showStartingYear: ! showStartingYear,
                            } )
                        }
                    />
                    { showStartingYear && (
                        <TextControl
                            label={ __(
                                'Starting year',
                                'test-block'
                            ) }
                            value={ startingYear || '' }
                            onChange={ ( value ) =>
                                setAttributes( { startingYear: value } )
                            }
                        />
                    ) }
                </PanelBody>
            </InspectorControls>

ここまでの変更を管理画面:ブロックを再読込して確認します。入力内容も保存されることも確認してください。

管理画面のビュワーに内容を反映させる

今まで設定してきた定数、showStartingYear, startingYearの2つをビュワーに反映させます。edit.jsに追記と変更します。

//追記 定数設定とreturnの間に分岐する変数設置
let displayDate;
if ( showStartingYear && startingYear ) {
    displayDate = startingYear + '–' + currentYear;
} else {
    displayDate = currentYear;
}

//変更 Edit()関数の最後で変数を出力
<p { ...useBlockProps() }>© { displayDate } YourSiteName.</p>

ここまでの変更を管理画面:ブロックを再読込して、開始年が表示されたことを確認します。トグルコントロールに合わせて表示が切り替わることも確認出来ます。

render.php フロント側のフッターに反映させる

render.phpには、Wordpressテンプレートタグ以外にも以下の変数が準備されています。これらの変数(配列)を利用し、フロント側に反映させていきます。

  • $attributes (array): ブロックの属性
  • $content (string): 静的に保存されたブロックのコンテンツ
  • $block (WP_Block): ブロックに格納された情報全て(インスタンス)
<?php
$starting_year = null;
$current_year = date("Y");//現在の年

//開始年があれば変数を上書き
if ( !empty($attributes['showStartingYear']) && !empty($attributes['startingYear']) ){
	$starting_year = "{$attributes['startingYear']}-";
}
?>
<p <?php echo get_block_wrapper_attributes(); ?>>
<small>© <?php echo $starting_year . $current_year;?> <?php bloginfo('name');?>.</small>
</p>

フロント側のフッターを再読込して、公開年が表示されたことを確認します。

ブロック開発 静的レンダリング

上記までは、データベースに格納されたデータから、プラグインのブロックを経由して最終的なアウトプットをしています。この処理により、プラグインのブロックを経由しなくても警告は出ますが出力できるようになります。この静的レンダリング処理を行うことで、プラグインを削除しても表示が外れなくなります。また、コンテンツはカスタムHTMLブロックとして、簡単に段落ブロックに変換できます。静的レンダリングに、動的レンダリングを混ぜることも可能です。

重要:現在は途中段階で確認をしないようにしてください。途中段階で確認をしてしまった場合、管理画面自体に不具合が起きる可能性があります。エディターが暗転して動かなくなった場合、プラグインを停止てから編集前の状態に戻し、別画面などの他のアプローチでブロックを削除して保存。プラグインを再度動かしてから、ブロックを入れ直してください。

静的コンテンツを保存するsave.jsを作成

/srcにsave.jsファイルを作成し、edit.jsに似た下記のsave関数のコードを入力します。save関数の詳細については、WordPress公式ドキュメントを参考にしてください。テーマエディターでの閲覧はJavascriptの編集がすべて終わってから利用できるようになります。

//save.js

import { useBlockProps } from '@wordpress/block-editor';
 
export default function save() {
    return (
        <p { ...useBlockProps.save() }>
            { 'Copyright Date Block – hello from the saved content!' }
        </p>
    );
}

index.jsで、save.jsファイルを連携

さらに、このsave.jsファイルをindex.jsファイルにインポートとプロパティを追記し、利用可能な状態にします。この更新をしてもすぐには機能を利用できません。

//index.js

//追記
import save from './save';


//saveプロパティを追記
registerBlockType( metadata.name, {
    icon: calendarIcon,
    edit: Edit,
    save //追記
} );

型定義と静的コンテンツを生成し、保存

以下のようにblock.jsonとsave.jsを更新していきます。現状では、currentYearが動的なプロパティのため、エラーが出てしまっています。これを解消するため、block.jsonのattributesに新しいプロパティを定義し、save.jsにも対応させます。save.jsには、現在の年数が未記入の場合、何もせずに返す処理を入れておきます。

//block.json

//変更箇所 fallbackCurrentYearを追加
"attributes": {
    "fallbackCurrentYear": {
        "type": "string"
    },
    "showStartingYear": {
        "type": "boolean"
    },
    "startingYear": {
        "type": "string"
    }
},
//save.js

//変更箇所 Propsの記述に注意
export default function save( { attributes } ) {

    const { fallbackCurrentYear, showStartingYear, startingYear } = attributes;
    if ( ! fallbackCurrentYear ) { return null; }//現在の年がなければ静的データを作らずに戻す

    let displayDate;
    if ( showStartingYear && startingYear ) {
        displayDate = `${startingYear}–${fallbackCurrentYear}`;
    } else {
        displayDate = fallbackCurrentYear;
    }

    return (
        <p { ...useBlockProps.save() }>© { displayDate } YourSiteName.</p>
    );

}

edit.jsで、現在の年を保存

fallbackCurrentYearの値を設定する必要があります。edit.jsに記述をしていきます。なお、ReactのuseEffectはレンダーのあとに処理される。useEffectの詳しい解説はこちら

//edit.js

//追加 importの並びに挿入
import { useEffect } from 'react';


//追加 定数fallbackCurrentYear
const { fallbackCurrentYear, showStartingYear, startingYear } = attributes;


//追加 Edit()関数内、定数設定の下辺り Reactの外部システム連携機能を使い、fallbackCurrentYearに値を設定
// ブロックロードのとき、fallbackCurrentYear が設定されていなければ、現在の年に設定する
useEffect( () => {
    if ( currentYear !== fallbackCurrentYear ) {
        setAttributes( { fallbackCurrentYear: currentYear } );
    }
}, [ currentYear, fallbackCurrentYear, setAttributes ] );

render.phpで、静的と動的コンテンツを分岐表示

フロント側に、動的コンテンツよりも、静的に保存されたコンテンツを優先して表示するプログラムを組みます。このとき、下記の変数や配列を利用していきます。

  • $attributes (array): ブロックの属性
  • $content (string): 静的に保存されたブロックのコンテンツ
  • $block (WP_Block): ブロックに格納された情報全て
//render.php

$current_year = date( "Y" );//現在の年
 
// 静的or動的なレンダリングのどちらを利用するのか分岐
if ( isset( $attributes['fallbackCurrentYear'] ) && $attributes['fallbackCurrentYear'] === $current_year ) {
 
	// 静的レンダリング
	// 現在の年はフォールバックと同じ。save.js 関数で保存された、データベース内のブロックコンテンツを使用する
    $block_content = $content;

} else {
 
	// 動的レンダリング
	// 現在の年はフォールバックと異なる。更新されたブロックコンテンツをレンダーする
    if ( ! empty( $attributes['startingYear'] ) && ! empty( $attributes['showStartingYear'] ) ) {
        $display_date = $attributes['startingYear'] . '–' . $current_year;
    } else {
        $display_date = $current_year;
    }
 
    $block_content = '<p ' . get_block_wrapper_attributes() . '>© ' . esc_html( $display_date ) . ' ' . get_bloginfo('name') . '</p>';
}

echo wp_kses_post( $block_content );

まとめ

ここまで、ブロック開発の始め方は終わりです。更に細かい詳細は、公式ドキュメントにもある下記のリンクを参考にしてください。


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です