ダイナミックカスタムブロック作成(WordPress)~その2~

前回、投稿IDを入力すると、入力したIDのタイトル、サムネイル、リンクを取得して表示するものを作成しました。
しかし、実際の表示を確認するには、プレビューを開くか、保存をしてページを開かないと確認ができませんでした。

もう少し使いやすくするために、ブロックにプレビュー機能を付けたいと思います。
プレビュー機能を付けることにより、編集画面上でも実際の表示を確認できます。
※ソースは前回のものを使用します。

ServerSideRenderコンポーネント

ServerSideRenderコンポーネントを使用すると、編集画面でrender_callback関数に基づいたレンダリングを確認できます。

ServerSideRender コンポーネントを@wordpress/editor パッケージからインポートします。

ServerSideRenderコンポーネントは、ブロックの名前(識別子)をblockプロパティに指定する必要があります。
これはprops.nameで取得ができます

レンダリングに必要な情報(ここでは、投稿ID)をattributeプロパティに指定します。

src/edit.js

//SeverSideRenderコンポーネントをインポート
import { ServerSideRender } from '@wordpress/editor';

export default function Edit(props) {
	//props経由でプロパティを変数に分割代入
	const {attributes: {postID}, setAttributes, className} = props;
	
	return (
		<div className={className} { ...useBlockProps() }>
			{/* プレビューと分けるため編集部分を div class="editMode" で囲む */}
			<div class="editMode">
				<div>sample dynamic block</div>
				<TextControl
					label='投稿IDを入力' //ラベルの表記を設定
					type='number' //inputタグのtypeを設定
					value={postID} //保存されている属性(投稿ID)を表示
					//入力された値を属性に登録する
					onChange={ ( newId ) => setAttributes({ postID: parseInt(newId) })}
				/>
			</div>

			{/* ServerSideRenderコンポーネントを追加 */}
			<div class="previewMode">
				<div>プレビュー</div>
				<ServerSideRender
					block={props.name} //ブロックの名前(識別子)を設定
					attributes={{
						postID: postID //保存されている属性(投稿ID)を表示
					}}
				/>
			</div>
		</div>
	);
}

プレビュー部分が見ずらいので、少し出力するHTMLとCSSを編集します。

sample-dynamic-block.php

本文の冒頭部分を表示するように編集します。

function sample_dynamic_block_render($attr, $content) {
	if($attr['postID'] > 0) {

		    //省略

			//本文の一部を取得
			$postContent = strip_tags($selectPost->post_content);
			$postContent = trim($postContent);
			$excerpt = mb_substr($postContent, 0, 75);

			//出力されるHTMLを編集
			ob_start();
			?>
			<div>
				<a class="postWrap" href="<?php print $link; ?>">
					<img src="<?php print $thumbUrl; ?>">
					<div class="postDetail">
						<div class=postTitle>
							<?php print $title; ?>
						</div>
						<p class="excerpt"><?php print $excerpt ?></p>
					</div>
				</a>
			</div>
			<?php
			$output = ob_get_contents();
			ob_end_clean();

			return $output;
		}
	}
}

src/editor.scss

編集画面のみ適用されるので、実際のページも同じデザインにする場合は、
src/sytle.scss を編集する必要があります。

.wp-block-create-block-sample-dynamic-block {
	border: 1px dotted #f00;

	/* 追加 */
	.previewMode {
		background: #fff;

		.previewTitle {
			color: #000;
		}

		img {
			width: 200px;
		}

		.postWrap  {
			display: flex;
			align-items: center;

			.postDetail {
				padding: 10px;

				.postTitle {
					margin-bottom: 8px;
				}
			}
		}

		a {
			display: inline-block;
		}
	}
}

投稿IDの入力の下にプレビューが表示されました。
※CSSは、実際に表示するデザインになる様に編集してください。

プレビューボタンの追加

プレビュー画面が常に表示されていると編集画面が見づらくなるので、
ツールバーにプレビューボタンを追加して、プレビュー表示と編集画面を切り替えられるようにします。

sample-dynamic-block.php

「attributes」に「isEditMode」(編集画面)を追加します。
現在の画面の状態(編集画面 or プレビュー)を表す属性になります。

function create_block_sample_dynamic_block_block_init() {
	register_block_type( __DIR__ . '/build', array(
		//レンダリング用のコールバック関数を設定
		'render_callback' => 'sample_dynamic_block_render',
		//入力された値(投稿ID)を保存するための属性を追記
		'attributes' => [
			'postID' => [
				'type' => 'number',
				'default' => 0
			],
			//表示画面の状態を管理する属性を追加
			'isEditMode' => [
				'type' => 'boolean',
				'default' => true
			]
		]
	));
}

src/edit.js

ツールバーにプレビューボタンを追加するので、
BlockControls、Button、Toolbar コンポーネントをインポートします。

//BlockControlsコンポーネントをインポート
import { BlockControls } from '@wordpress/block-editor';
//Button、Toolbarコンポーネントを追加
import { Button, Toolbar } from '@wordpress/components';

propsのisEditModeプロパティを変数に代入。

const {attributes: {postID, isEditMode}, setAttributes, className} = props;

ツールバーにプレビューボタンを追加して表示する関数(getBlockControls)を追加します。
ボタンの表示切替は、isEditModeの値により切り替わるようにします。

const getBlockControls = () => {
		return (
			<BlockControls>
				<Toolbar>
					<Button
						label={ isEditMode ? 'Preview' : 'Edit'} //isEditModeの値によって、ラベルを切り替える
						icon={ isEditMode ? 'format-image' : 'edit' } //isEditModeの値によって、アイコンを切替る
						className='read-together-btn'
						onClick={() => {
							//clickされると値が反転
							setAttributes({ isEditMode: !isEditMode })}
						}
					/>
				</Toolbar>
			</BlockControls>
		);
	}

出力内容部分もisEditModeの値によって、切り替わるように編集します。

return (
		[
			getBlockControls(),
			<div className={className} { ...useBlockProps() }>

				{/* trueの場合、編集画面を表示 */}
				{ isEditMode && 
					//プレビューと分けるため編集部分を div class="editMode" で囲む
					<div class="editMode">
						<div>sample dynamic block</div>
						<TextControl
							label='投稿IDを入力' //ラベルの表記を設定
							type='number' //inputタグのtypeを設定
							value={postID} //保存されている属性(投稿ID)を表示
							//入力された値を属性に登録する
							onChange={ ( newId ) => setAttributes({ postID: parseInt(newId) })}
						/>
					</div>
				}
				{/* falseの場合、プレビュー画面を表示 */}
				{ !isEditMode &&
					//ServerSideRenderコンポーネントを追加
					<div class="previewMode">
						<div class="previewTitle">プレビュー</div>
						<ServerSideRender
							block={props.name} //ブロックの名前(識別子)を設定
							attributes={{
								postID: postID //保存されている属性(投稿ID)を表示
							}}
						/>
					</div>
				}

			</div>
		]
	);

編集モード

プレビューモード

まとめ

今回、プレビュー機能を追加することで、編集画面上でも実際の表示を確認ができるようになり、
使いやすくなったと思います。

ツールバーへのボタン追加もいろいろと応用できるかと思いますので、
ぜひ、参考にしていただければと思います。

お問い合わせ

サービスに関するご相談やご質問などこちらからお問い合わせください。

03-55107260

受付時間 10:00〜17:00