チュートリアル: はじめてのブロック作成
このチュートリアルでは「Copyright Date ブロック」(著作権と年表示ブロック) を作成します。著作権シンボル (©)、現在の年、開始の年 (オプション) を表示する、基本的ながら実用的な、しばしばサイトのフッターでよく見かけるタイプのブロックです。
ここでは create-block
パッケージを使用して、ブロックプラグインのひな形作成から各ファイルの修正まで、完全な手順を紹介します。このチュートリアルを実行するにあたっては WordPress の開発経験があると有益ですが、必須ではありません。
このチュートリアルを終えるとブロック開発の基礎を明確に理解し、自身の WordPress ブロック作成に必要なスキルを得られます。
ここで作成するブロック
このチュートリアルでは以下のようなブロックを作成します。
WordPress Playground では完成したチュートリアルを試すことができます。また クイックスタートガイド を使用すると、ローカルの WordPress 環境に完全なブロックプラグインをインストールできます。
準備
このチュートリアルを実行するには、以下が必要です。
- コードエディター
- Node.js 開発ツール
- ローカル WordPress 環境
もしまだ準備できていなければ、ブロック開発環境のドキュメントを参照してください。セットアップが完了したら、ここに戻ってきてください。
このチュートリアルでは、
wp-env
を使用して WordPress のローカル開発環境を作成します。すでに好みのローカル開発ツールがあれば、自由にそのツールを使用してください。
ブロックのひな型の作成
Copyright Date ブロックを作成する最初のステップは、@wordpress/create-block
パッケージを使用した、ブロックの初期構成のひな形の作成です。
このパッケージの使用方法については、create-block 入門 を参照してください。
コンピュータ上の任意のディレクトリ (フォルダ) から create-block
を使用し、次に wp-env
を使用すると、新しいブロックプラグインをインストールして有効化した、ローカルの WordPress 開発環境を作成できます。
まず、ブロックプラグインを置くディレクトリを選択するか、オプションで新しいフォルダ「Block Tutorial」を作成します。ターミナルを開き、このディレクトリに cd
します。そして以下のコマンドを実行します。
wp-env
を使用していなければ、代わりにターミナルを使用してローカルの WordPress インストール内のplugins/
フォルダに移動して、以下のコマンドを実行します。
npx @wordpress/create-block@latest copyright-date-block --variant=dynamic
cd copyright-date-block
このコマンドを実行すると、plugins フォルダ内に新しいディレクトリ copyright-date-block
が作成されます。このディレクトリには、ブロックのカスタマイズを始めるために必要なすべての初期ファイルが含まれています。
このコマンドはまた、copyright-date-block
をスラッグとしてブロックの基本構成を設定します。このスラッグはWordPress 内で一意にブロックを識別します。
コマンドに
--variant=dynamic
フラグが指定されていることにお気づきかもしれません。これはcreate-block
に対して動的にレンダーされるブロックのひな形を作成するよう伝えます。このチュートリアルの後半では、動的レンダリングと静的レンダリングについて学び、静的レンダリングをこのブロックに追加します。
WordPress 管理画面のプラグインページに移動し、プラグインが有効になっていることを確認してください。次に、新しいページまたは投稿を作成し、Copyright Date ブロックを挿入できることを確認してください。挿入すると以下のようになります。
ファイルの確認
ひな形のブロックを修正する前に、プラグインのファイルの構成を確認することが重要です。コードエディターでプラグインフォルダを開きます。
次に、ブロックのファイル構成を参照して、各ファイルが何をするのかの概要をざっと眺めてください。今すぐには理解できなくても構いません。このチュートリアルを通して、各ファイルの使い方を学びます。
動的ブロックのひな形を作成したため、
save.js
ファイルはありません。チュートリアルの後半で、このファイルをプラグインに追加して、静的レンダリングを有効化します。
初期セットアップ
できるだけシンプルな Copyright Date ブロックを作成するところから始めましょう。動的にレンダーされ、著作権記号 (©) と現在の年を表示するだけのブロックを作成します。いくつかのコントロールも追加して、ユーザーがフォントサイズとテキストの色を変更できるようにします。
次のステップに進む前に、ターミナルでプラグインディレクトリから npm run start
を実行します。このコマンドは /src
フォルダ内の各ファイルの変更を監視し、ファイルを保存するたびに、ブロックのビルドファイルを更新します。
詳細については、ブロックエディターでの JavaScript の利用を参照してください。
block.json の更新
/src
フォルダ内の block.json
ファイルを開きます。
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"icon": "smiley",
"description": "Example block scaffolded with Create Block tool.",
"example": {},
"supports": {
"html": false
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"render": "file:./render.php",
"viewScript": "file:./view.js"
}
このファイルの詳細については block.json を参照してください。
ひな形作成のプロセスでこのファイルを作成したため、Copyright Date ブロックのニーズに合わせるには若干の更新が必要です。
ブロックの説明の変更
まずアイコンを削除し、より適切な説明を追加することから始めます。カスタムアイコンを後で追加します。
"icon":
行を削除"description":
の説明文を「Display your site’s copyright date.」(サイトの著作権と公開年を表示) で置換- ファイルを保存
エディターを更新すると、ブロックからスマイルのアイコンが消え、説明文が更新されていることが確認できます。
ブロックサポートの追加
次に、いくつかのブロックサポートを追加します。ユーザーはブロックのフォントサイズとテキスト色を自由に設定できるようになります。
カスタム機能の構築を検討する前に、常にネイティブのブロックサポートを使用してください。このアプローチにより、ユーザーはブロック間で一貫した編集体験を得られ、ブロックもわずか数行のコードでコア機能の恩恵を受けられます。
block.json
ファイル内の supports
セクションを以下のように更新します。
"supports": {
"color": {
"background": false,
"text": true
},
"html": false,
"typography": {
"fontSize": true
}
},
"text": true
でテキスト色のサポートを有効にすると、デフォルトで背景色も有効になることに注意してください。そのままでも構いませんが、このチュートリアルでは必要ないため、"background": false
を設定しています。
ファイルを保存し、エディターでブロックを選択します。これで、設定サイドバーに色とタイポグラフィの両方のパネルが表示されます。設定を変更して、変化の様子を見てみましょう。
不要なコードの削除
簡単のため、Copyright Date ブロックのすべてのスタイルは、ブロックサポートの color
と typography
で制御します。またこのブロックは、フロントエンドの JavaScript を持ちません。したがって block.json
ファイル内で、スタイルシートや viewScript
を指定する必要はありません。
editorStyle
行を削除style
行を削除viewScript
行を削除- ファイルを保存
エディターを更新すると、ブロックのスタイルが現在のテーマと一致していることがわかります。
すべてをひとつに
最終的に block.json
ファイルは以下のようになります。
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"description": "Display your site's copyright date.",
"example": {},
"supports": {
"color": {
"background": false,
"text": true
},
"html": false,
"typography": {
"fontSize": true
}
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"render": "file:./render.php"
}
index.js の更新
ブロック自身の機能を作り始める前に、もう少しクリーンアップして、ブロックにカスタムアイコンを追加しましょう。
index.js
ファイルを開いてください。これはブロックのメインの JavaScript ファイルで、クライアントでのブロックの登録に使用されます。クライアントサイドとサーバーサイドの登録については、ブロックの登録を参照してください。
まず、registerBlockType
関数を見てください。この関数は、インポートした block.js
ファイルから取得したブロックの名前と、ブロックの設定オブジェクトを受け取ります。
import Edit from './edit';
import metadata from './block.json';
registerBlockType( metadata.name, {
edit: Edit,
} );
デフォルトでは、オブジェクトは edit
プロパティだけを含みますが、icon
を含む多くのプロパティを追加できます。これらのプロパティのほとんどは既に block.json
で定義されていますが、カスタム SVG を使用するにはここでアイコンを指定する必要があります。
カスタムアイコンの追加
Gutenberg Storybookのカレンダーアイコンを使用して、次のように関数に SVG を追加します。
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>
);
registerBlockType( metadata.name, {
icon: calendarIcon,
edit: Edit
} );
すべてのブロックのアイコンは24ピクセルの正方形でなければなりません。上の
viewBox
パラメータに注意してください。
index.js
ファイルを保存し、エディターを更新します。デフォルトの代わりに、カレンダーアイコンが表示されます。
この時点でブロックのアイコンと説明は正しくなり、ブロックサポートによりフォントのサイズとテキストの色を変更できます。さて、いよいよブロックの実際の機能に移りましょう。
edit.js の更新
edit.js
ファイルは、このブロックがどのように機能し、どのようにエディターに表示されるかを制御します。現在、ユーザーにはメッセージ「Copyright Date Block – hello from the editor!」が表示されます。これを変更しましょう。
ファイルを開き、Edit()
関数がデフォルトのメッセージを含む paragraph タグを返すことを確認してください。
export default function Edit() {
return (
<p { ...useBlockProps() }>
{ __(
'Copyright Date Block – hello from the editor!',
'copyright-date-block-demo'
) }
</p>
);
}
このコードは実際よりも少し複雑に見えます。
useBlockProps()
はブロックラッパー内に、エディターで必要とされるすべての CSS クラスとスタイルを出力します。これには、先に追加したブロックサポートの提供するスタイルも含まれます。__()
はテキスト文字列の国際化に使用されます。
ブロックラッパーのドキュメントでは、ブロックのマークアップラッパーに適切な属性を持たせる方法を紹介しています。
ところでこのブロックの主な目的は、著作権記号 (©) と現在の年の表示でした。そのためまず現在の年を文字列形式で取得する必要があります。以下のコードがこれを行います。
const currentYear = new Date().getFullYear().toString();
次に関数を更新して、正しい情報を表示します。
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<p { ...useBlockProps() }>© { currentYear }</p>
);
}
edit.js
ファイルを保存し、エディターを更新します。著作権マーク (©) と現在の年が表示されます。
render.php の更新
エディター上ではブロックは正しく動作していますが、フロントエンドではデフォルトのブロックメッセージが表示されたままです。これを修正するには render.php
ファイルを開きます。以下のコードがあります。
<?php
...
?>
<p <?php echo get_block_wrapper_attributes(); ?>>
<?php esc_html_e( 'Copyright Date Block – hello from a dynamic block!', 'copyright-date-block' ); ?>
</p>
エディター内での useBlockProps()
関数と同様に、get_block_wrapper_attributes()
は、ブロックのラッパー 内に必要なすべての CSS クラスとスタイルを出力します。あとはコンテンツのみ、更新が必要です。
PHP で現在の年を取得するには、date( "Y" )
を使用します。render.php
は次のようになります。
<?php
...
?>
<p <?php echo get_block_wrapper_attributes(); ?>>© <?php echo date( "Y" ); ?></p>
ファイルを保存し、エディターとフロントエンドでブロックが正しく表示されることを確認します。
クリーンアップ
create-block
パッケージを使用してブロックのひな形を作成すると、必要のないファイルが含まれる場合があります。このチュートリアルでも、ブロックはスタイルシートやフロントエンド JavaScipt を使用していませんので、以下の操作でプラグインの src/
フォルダをクリーンアップします。
edit.js
ファイルで、editor.scss
の import 行を削除する。index.js
ファイルで、style.scss
の import 行を削除する。- editor.scss、style.scss、view.js ファイルを削除する。
最後に、変更がすべて保存されていることを確認して、npm run start
コマンドを終了します。npm run build
を実行して、コードを最適化し、本番環境用にビルドします。
これで完全に機能する WordPress ブロックを構築できました。しかし、これで終わりではありません。次のセクションでは、さらに機能を追加し、静的レンダリングを有効にします。
ブロック属性の追加
作成した Copyright Date ブロックは現在の年を表示していますが、開始の年も表示するにはどうすればよいでしょう ?
この機能のためには、ユーザーがブロックのどこかで公開年を入力する必要があります。また、表示のオンオフを切り替える機能も必要です。
さまざまな方法でこの機能を実装できますが、いずれの方法でもブロックの属性が必要です。属性は、ブロックのカスタムデータを保存し、ブロックのマークアップを変更できます。
この開始年を表示する機能を実現するには、開始年を保存する属性と、WordPress に開始年の表示の有無を伝える別の属性が必要です。
block.json の更新
ブロックの属性は通常、block.json
ファイルで指定します。ファイルを開き、example
プロパティの後に以下のセクションを追加してください。
"example": {},
"attributes": {
"showStartingYear": {
"type": "boolean"
},
"startingYear": {
"type": "string"
}
},
属性を定義する際には type
を指定しなければなりません。ここで showStartingYear
は true か false のため boolean
を設定しています。startingYear
は単なる文字列です。
ファイルを保存したら、エディターに移ります。
edit.js の更新
edit.js
ファイルを開きます。2つの作業を行う必要があります。
- ユーザーが開始年を入力でき、機能のオンオフを切り替えられるユーザーインターフェースを追加し、これらの設定を属性として保存する。
- 定義した属性に応じて、正しいコンテンツを表示するようにブロックを更新する。
ユーザーインターフェースの追加
このチュートリアルの前半ではブロックサポートを追加することで、自動的にブロックの設定サイドバーに、色とタイポグラフィのパネルを作成しました。InspectorControls
コンポーネントを使用すると、独自のカスタムパネルを作成できます。
Inspector コントロール
InspectorControls
は @wordpress/block-editor
パッケージに属しています。14行目にコンポーネント名を追加することで edit.js
ファイルにインポートできます。変更後は以下のようになります。
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
次に、Edit 関数を更新して、現在のブロックの内容と、文字列「Testing」を含む InspectorControls
コンポーネントを返します。適切な JSX 構文となるためにすべてを フラグメント (<></>
) で囲みます。結果は以下のようになります。
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
Testing
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}
ファイルを保存し、エディターを更新します。ブロックを選択すると、設定サイドバーにメッセージ「Testing」が表示されるはずです。
コンポーネントとパネル
さらにいくつかのコアコンポーネントを使用して、カスタムパネルと開始年表示機能のユーザーインターフェイスを追加します。PanelBody
、TextControl
、ToggleControl
を @wordpress/components
パッケージからインポートします。
edit.js
ファイルの他のインポートの下に以下の行を追加してください。
import { PanelBody, TextControl, ToggleControl } from '@wordpress/components';
次に、メッセージ「Testing」を PanelBody
コンポーネントでラップし、title
パラメータに「Settings」を設定します。その他のパラメータオプションについては、コンポーネントのドキュメントを参照してください。
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
<PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
Testing
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}
ファイルを保存し、エディターを更新します。新しい設定パネルが表示されるはずです。
Text コントロール
次のステップでは、メッセージ「Testing」を TextControl
コンポーネントで置き換え、ユーザーが startingYear
属性を設定できるようにします。ただし、その前に Edit()
関数に2つのパラメータを含める必要があります。
attributes
はブロックのすべての属性を含むオブジェクトです。setAttributes
は属性の値を更新する関数です。
これらのパラメータが含まれることで、showStartingYear
属性と startingYear
属性を取得できます。
Edit()
関数の先頭を次のように更新します。
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
...
Copyright Date ブロックに関連するすべての属性を見るには、
Edit()
関数の先頭にconsole.log( attributes );
を追加します。この方法は、カスタムブロックを作成し、テストする際に便利な方法です。
次に、メッセージ「Testing」を削除して、TextControl
を追加します。コンポーネントには以下が含まれます。
label
プロパティに「Starting year」を設定する。value
プロパティに属性startingYear
を設定する。onChange
プロパティは、値が変更されるたびにstartingYear
属性を更新する。
これらをまとめると、Edit()
関数は以下のようになります。
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
<PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
<TextControl
label={ __(
'Starting year',
'copyright-date-block'
) }
value={ startingYear || '' }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}
value
プロパティが値 startingYear || ''
になっています。記号 ||
は、論理和演算子と呼ばれます。startingYear
が空の場合に React で警告が出るのを防ぎます。詳しくは Controlled and uncontrolled components を参照してください。
ファイルを保存し、エディターを更新します。設定パネルにテキストフィールドが存在することを確認してください。また、開始年を追加し、ページを更新したときに値が保存されていることを確認してください。
Toggle コントロール
次に、開始年表示のオンオフを切り替えるトグルを追加します。これは showStartingYear
属性を設定する ToggleControl
コンポーネントで行えます。このコンポーネントには以下が含まれます。
label
プロパティ。「Show starting year」を設定する。checked
プロパティ。属性showStartingYear
を設定する。onChange
プロパティ。トグルがチェックされるたびにshowStartingYear
属性を更新する。
また「Starting year」テキスト入力を更新して、showStartingYear
が true
のときのみ表示されるようにします。これには &&
論理演算子を使用します。
Edit()
関数は以下のようになります。
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
<PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
<ToggleControl
checked={ !! showStartingYear }
label={ __(
'Show starting year',
'copyright-date-block'
) }
onChange={ () =>
setAttributes( {
showStartingYear: ! showStartingYear,
} )
}
/>
{ showStartingYear && (
<TextControl
label={ __(
'Starting year',
'copyright-date-block'
) }
value={ startingYear || '' }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
) }
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}
ファイルを保存し、エディターを更新します。トグルをクリックするとテキスト入力が表示され、ページを更新しても、トグルは有効なままです。
ブロックのコンテンツの更新
ここまでで、開始年を追加し、関連するブロック属性を更新するユーザーインターフェースを作成しました。次に、エディターで実際にブロックのコンテンツを更新します。
新しい変数 displayDate
を作ります。showStartingYear
が true
で、ユーザーが startingYear
を指定していれば、displayDate
に startingYear
と currentYear
を em ダッシュで区切って表示します。それ以外の場合は currentYear
を表示します。
コードは以下のようになります。
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + currentYear;
} else {
displayDate = currentYear;
}
let
で宣言した変数は、後で再割り当てされる可能性があることを意味します。const
で宣言した変数は、決して変更されないことを意味します。このコードはconst
を使用して書き換えられますが、これは個人の好みの問題です。
あとは currentYear
変数の代わりに displayDate
を使うようにブロックのコンテンツを更新するだけです。
Edit()
関数は以下のようになります。
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + currentYear;
} else {
displayDate = currentYear;
}
return (
<>
<InspectorControls>
<PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
<ToggleControl
checked={ !! showStartingYear }
label={ __(
'Show starting year',
'copyright-date-block'
) }
onChange={ () =>
setAttributes( {
showStartingYear: ! showStartingYear,
} )
}
/>
{ showStartingYear && (
<TextControl
label={ __(
'Starting year',
'copyright-date-block'
) }
value={ startingYear || '' }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
) }
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }>© { displayDate }</p>
</>
);
}
ファイルを保存し、エディターを更新します。設定パネルで変更を加えると、ブロックのコンテンツが正しく更新されることを確認してください。
render.php の更新
エディター側は完成しましたが、フロントエンドにはまだ開始年を表示する機能が追加されていません。render.php
ファイルを更新して、これを修正します。
まず、変数 $display_date
を追加して、上の Edit()
関数での実装を繰り返します。
この変数には startingYear
属性の値と $current_year
変数を em ダッシュで区切って表示するか、または showStartingYear
属性が false
のとき $current_year
の値だけを表示します。
render.php
では3つの変数が公開されています。これを使用してブロックの出力をカスタマイズできます。
$attributes
(array): ブロックの属性$content
(string): ブロックのデフォルトコンテンツ$block
(WP_Block): ブロックのインスタンス
コードは以下のようになります。
if ( ! empty( $attributes['startingYear'] ) && ! empty( $attributes['showStartingYear'] ) ) {
$display_date = $attributes['startingYear'] . '–' . $current_year;
} else {
$display_date = $current_year;
}
あとは $current_year
変数の代わりに $display_date
を使うようにブロックの内容を更新するだけです。
最終的な render.php
ファイルは次のようになります。
<?php
$current_year = date( "Y" );
if ( ! empty( $attributes['startingYear'] ) && ! empty( $attributes['showStartingYear'] ) ) {
$display_date = $attributes['startingYear'] . '–' . $current_year;
} else {
$display_date = $current_year;
}
?>
<p <?php echo get_block_wrapper_attributes(); ?>>
© <?php echo esc_html( $display_date ); ?>
</p>
ファイルを保存し、サイトのフロントエンドに正しいブロックコンテンツが表示されていることを確認してください。
以上で動的にレンダーされるカスタムブロックが完成しました。ブロックサポート、WordPress のコアコンポーネント、カスタム属性を利用しています。追加の機能もあり、著作権と日付を表示するブロックとしては多くの場面で十分すぎる内容です。
しかし、次のセクションでは、ブロックに静的レンダリングを追加します。WordPress でブロックデータがどのように保存されるかを説明し、意図せずプラグインが無効になってしまった際の、フォールバックを実装します。
静的レンダリングの追加
ブロックは、動的レンダリング、静的レンダリング、またはその両方を利用できます。これまでに作成したブロックは、動的にレンダーされます。動的にレンダーされるブロックでは、ブロックのマークアップと関連した属性はデータベースに保存されますが、HTML 出力は保存されません。
静的にレンダーされるブロックは、常にブロックマークアップ、属性、出力をデータベース内に保存します。ブロックは2つを組み合わせ、静的な出力をデータベースに保存しながら、フロントエンドでさらに動的に拡張することもできます。
エディターからコードエディターに切り替えると、次のようになります。
<!-- wp:create-block/copyright-date-block {"showStartingYear":true,"startingYear":"2017"} /-->
これを段落ブロックのような静的にレンダーされるブロックと比較してみてください。
<!-- wp:paragraph -->
<p>This is a test.</p>
<!-- /wp:paragraph -->
段落の HTML は投稿コンテンツに格納され、データベースに保存されます。
動的レンダリングと静的レンダリングについては、ブロック開発の基本原理を参照してください。ほとんどのブロックは動的または静的のどちらかでレンダーされますが、両方の方法を利用するブロックも作成できます。
静的レンダリングを追加する理由
動的にレンダーされるブロックに静的レンダリングを追加しても引き続き render.php
ファイルがフロントエンドの出力を制御しますが、ブロックの HTML コンテンツはデータベースに保存されます。このことは、プラグインがサイトから削除されても、コンテンツが残ることを意味します。この Copyright Date ブロックの場合、コンテンツはカスタム HTML ブロックに戻り、簡単に段落ブロックに変換できます。
すべての状況で必要ではありませんが、動的にレンダーされるブロックに静的レンダリングを追加すると、意図せずプラグインが無効化された場合にフォールバックとして役立ちます。
またブロックのマークアップが、ブロックパターンやテーマテンプレートに含まれている場合を考えます。Copyright Date ブロックをインストールしていない状態で、テーマをインストールしたり、パターンを使用すると、ブロックが利用できないという通知は表示されますが、コンテンツは表示されます。
静的レンダリングを追加することは、WordPress でブロックコンテンツがどのように保存され、レンダーされるかを調べる良い方法でもあります。
save 関数の追加
まず、新しいファイル save.js
を src/
フォルダに追加します。このファイルに以下のコードを追加します。
import { useBlockProps } from '@wordpress/block-editor';
export default function save() {
return (
<p { ...useBlockProps.save() }>
{ 'Copyright Date Block – hello from the saved content!' }
</p>
);
}
これはオリジナルの edit.js
ファイルと同じように見えます。追加の情報については、ブロックラッパーのドキュメントを参照してください。
次に、 index.js
ファイルで、この save()
関数をインポートし、 registerBlockType()
関数に save プロパティを追加します。以下は更新したファイルの簡略版です。
import save from './save';
...
registerBlockType( metadata.name, {
icon: calendarIcon,
edit: Edit,
save
} );
オブジェクトのプロパティを定義する際、プロパティ名と変数名が同じであれば、省略形のプロパティ名を使用できます。上のコードの save
は save: save
の意味です。
save.js
と index.js
の両方のファイルを保存し、エディターを更新します。以下のようになるはずです。
心配しないでください。想定内のエラーです。ブラウザでインスペクタを開くと、次のようなメッセージが表示されるはずです。
このブロックバリデーションエラーは、save()
関数はブロックの内容を返すものの、以前に保存されたブロックが動的だったため、ブロックのマークアップに HTML が保存されていないために発生します。以下が現在のマークアップであることを思い出してください。
<!-- wp:create-block/copyright-date-block {"showStartingYear":true,"startingYear":"2017"} /-->
以降のステップで save()
関数を更新するたびに、このエラーが繰り返し表示されます。「ブロックのリカバリーを試行」をクリックして、ページを更新してください。
ブロックのリカバリーを実行した後、コードエディターを開くと、マークアップは以下のようになっています。
<!-- wp:create-block/copyright-date-block {"showStartingYear":true,"startingYear":"2017"} -->
<p class="wp-block-create-block-copyright-date-block">Copyright Date Block – hello from the saved content!</p>
<!-- /wp:create-block/copyright-date-block -->
静的レンダリングでブロックを構築すると、しばしばブロックのバリデーションエラーに遭遇しますが、問題ありません。save()
関数の出力は、投稿コンテンツの HTML と正確に一致しなければなりませんが、機能を追加するたびに同期は失われます。ブロックを完全に構築し終わったときにバリデーションエラーがなければ、それで大丈夫です。
save.js の更新
次に、save()
関数の出力を更新して、正しい内容を表示するようにします。まず、edit.js
で使用したのと同じ方法を繰り返します。
- 関数に
attributes
パラメータを追加する - 変数
showStartingYear
とstartingYear
を定義する currentYear
変数を定義するcurrentYear
、showStartingYear
、startingYear
の値に応じてdisplayDate
変数を定義する
結果は以下のようになります。
export default function save( { attributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + currentYear;
} else {
displayDate = currentYear;
}
return (
<p { ...useBlockProps.save() }>© { displayDate }</p>
);
}
ファイルを保存し、エディターを更新します。「ブロックのリカバリーを試行」をクリックし、ページを更新します。コードエディターを確認すると、ブロックマークアップは次のようになっているはずです。
<!-- wp:create-block/copyright-date-block {"showStartingYear":true,"startingYear":"2017"} -->
<p class="wp-block-create-block-copyright-date-block">© 2017–2023</p>
<!-- /wp:create-block/copyright-date-block -->
この時点で、すべてが完成したように見えます。ブロックのコンテンツはデータベースに HTML として保存され、フロントエンドの出力は動的にレンダーされます。しかし、まだ対処しなければならないことがいくつかあります。
2023年にブロックが追加されたページを、2024年に更新したいとします。フロントエンドは期待通りに更新されますが、エディターではブロックのバリデーションエラーが発生します。save()
関数は2024年であることを知っていますが、データベースに保存されたブロックのコンテンツは2023年のままのためです。
次のセクションでこれを修正します。
静的にレンダーされるブロック内の動的コンテンツの処理
一般的に、静的にレンダーされるブロック内では動的なコンテンツは避けたいところです。これが、動的レンダリングを指すときに「動的」という言葉が使われる理由の一部です。
とはいえ、このチュートリアルでは両方のレンダリング方法を組み合わせており、年が変わったときにブロックバリデーションエラーを抑止するには、もう少しコードが必要です。
問題の根本は、save()
関数の中で currentYear
変数が動的に設定されていることです。本来であれば、関数内で静的な変数として設定すべきです。これを追加の属性で解決します。
新しい属性の追加
block.json
ファイルを開き、新しい属性 fallbackCurrentYear
を追加します。ファイルの attributes
セクションは以下のようになります。
"attributes": {
"fallbackCurrentYear": {
"type": "string"
},
"showStartingYear": {
"type": "boolean"
},
"startingYear": {
"type": "string"
}
},
次に save.js
ファイルを開き、currentYear
の代わりに新しい fallbackCurrentYear
属性を使用します。更新した save()
関数は次のようになります。
export default function save( { attributes } ) {
const { fallbackCurrentYear, showStartingYear, startingYear } = attributes;
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + fallbackCurrentYear;
} else {
displayDate = fallbackCurrentYear;
}
return (
<p { ...useBlockProps.save() }>© { displayDate }</p>
);
}
このとき fallbackCurrentYear
が undefined (未定義) であれば何が起きるでしょう ?
以前は currentYear
は関数内で定義されていたため、save()
関数には常に、仮に showStartingYear
や startingYear
が未定義であっても、返すコンテンツがありました。
著作権記号のみを返す代わりに、fallbackCurrentYear
が設定されていなければ null
を返す条件を追加しましょう。一般に不完全な HTML データを保存するよりも、何も保存しない方が優れます。
最終的な save()
関数は次のようになります。
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 }</p>
);
}
block.json
ファイルと save.js
ファイルの両方を保存します。これ以上の変更はありません。
edit.js での属性の設定
save()
関数は新しい fallbackCurrentYear
を使用するため、どこかで設定する必要があります。Edit()
関数を使いましょう。
edit.js
ファイルを開き、まず fallbackCurrentYear
変数を Edit()
関数の先頭で、他の属性と一緒に定義します。次に、関数内での動きを確認します。
エディターでブロックがロードされると、currentYear
変数が定義されます。そして、この関数はこの変数を使ってブロックのコンテンツをを設定します。
次に、fallbackCurrentYear
属性がまだ設定されていなければ、ブロックがロードされたときにfallbackCurrentYear
属性に currentYear
を設定します。
if ( currentYear !== fallbackCurrentYear ) {
setAttributes( { fallbackCurrentYear: currentYear } );
}
これで動作しますが、ブロックが初期化されたときにこのコードが一度だけ実行されるようにすることで改善できます。それには、useEffect
React フックを使用します。このフックの使い方については、React のドキュメントを参照してください。
まず、以下のコードで useEffect
をインポートします。
import { useEffect } from 'react';
次に、上の setAttribute()
コードを useEffect
でラップし、このコードを Edit()
関数の currentYear
定義の後に置きます。結果は以下のようになります。
export default function Edit( { attributes, setAttributes } ) {
const { fallbackCurrentYear, showStartingYear, startingYear } = attributes;
// 現在の年を取得し、文字列であることを確認する
const currentYear = new Date().getFullYear().toString();
// ブロックロードのとき、fallbackCurrentYear がまだ設定されていなければ、
// 現在の年に設定する
useEffect( () => {
if ( currentYear !== fallbackCurrentYear ) {
setAttributes( { fallbackCurrentYear: currentYear } );
}
}, [ currentYear, fallbackCurrentYear, setAttributes ] );
...
エディターでブロックが初期化されると、fallbackCurrentYear
属性はすぐに設定されます。この値は save()
関数で利用できるようになり、正しいブロックのコンテンツがブロックのバリデーションエラーなしで表示されます。
注意する点は、年が変わる場合です。Copyright Date ブロックが2023年にページに追加され、2024年に編集された場合、fallbackCurrentYear
属性は currentYear
と一致せず、属性は自動的に 2024
に更新されます。これにより、save()
関数が返す HTML も更新されます。
ブロックのバリデーションエラーは発生しませんが、エディターはページに変更を検知し、更新を促します。
render.php の最適化
最後のステップは render.php
ファイルの最適化です。currentYear
属性と fallbackCurrentYear
属性が同じであれば、ブロックのコンテンツを動的に作成する必要はありません。既にデータベースに保存されていて、$content
変数を通じて render.php
ファイルで利用できます。
一方 currentYear
と fallbackCurrentYear
が一致しなければ、生成したコンテンツをレンダーするようにファイルを更新します。
$current_year = date( "Y" );
// どのコンテンツを表示するかを決定する。
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 ) . '</p>';
}
echo wp_kses_post( $block_content );
以上です。これで、動的レンダリングと静的レンダリングの両方を利用するブロックが完成しました。
まとめ
おめでとうございます。チュートリアルを完了し、オリジナルの Copyright Date ブロックを構築しました。このチュートリアルを通して、WordPress のブロック開発における確かな基礎を身につけ、自身のブロックを構築する準備が整いました。
最後にこのチュートリアルの完全なコードは、GitHub の Block Development Examples リポジトリにあります。
これからスキルを磨きたい方、より高度なプロジェクトに取り組みたい方、WordPress の最新トレンドを知りたい方には、以下の情報やサイトがブロック開発のスキルアップに役立ちます。
- ブロック開発環境
- ブロック開発の基本原理
- WordPress 開発者ブログ
- Block Development Examples | GitHub リポジトリ
どんなエキスパートも、かつては初心者だったことを忘れないでください。学び続け、実験し続け、そして最も重要な教えとして、WordPress での構築を楽しんでください。
最終更新日: