今回はsave
コンポネントを破棄し、サーバーサイドでレンダリングする方法です。
saveを削除
save
ではフロント表示用のコンポーネントを定義していました。
これをサーバーサイドでレンダリングすることが出来ます。
そうなるとsave
は不要になるので除外します。
index.ts
のregisterBlockType()
からsave
を変更します。
import { BlockConfiguration, registerBlockType } from '@wordpress/blocks';
import Edit from './edit';
import save from './save';
import metadata from './block.json';
import KurageExampleBlockProps from './props';
import './style.scss';
const blockConf: BlockConfiguration<KurageExampleBlockProps> =
{
attributes: {},
title: metadata.title,
category: metadata.category,
edit: Edit,
save: props => null,
};
registerBlockType(metadata.name, blockConf);
save: props => null,
これまでのsave
コンポーネントを一旦無視して変更します。
IDEにsave
が使われてないって文句をいわれる時はimportをコメントアウトしてください。
プレビューを見ると何も表示されなくなってます。
nullを返したんだから当然です。
サーバーサイドの変更
次にPHP側の変更です。
kurage-worker.php
を変更します。
function create_block_kurage_worker_block_init() {
register_block_type(
__DIR__ . '/build',
[
'render_callback' => function($attr, $content)
{
return 'Hello Dynamic Kurage!';
}
]
);
}
add_action( 'init', 'create_block_kurage_worker_block_init' );
register_block_type()
の第二引数はオプション(連想配列)です。
render_callback
にコールバック関数を指定し、その戻り値がsave
の変わりに描画されます。
この時、コールバックの$content
は本来save
が描画するはずのHTMLのようです。
もしedit
を変更してなければ以下のようなHTMLが送られてきます。
save
が以下の場合なら、
export default (props: BlockSaveProps<KurageExampleBlockProps>) =>
{
return (
<div { ...useBlockProps.save() }>
<p>Hello Kurage !!</p>
</div>
);
}
$content
で受け取る値はこうなります。
<div class="wp-block-create-block-kurage-worker"><p>Hello Kurage !!</p></div>
$attr
は属性を取得します。
属性
属性を使っていきます。
block.json
にattributes
を追加。
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "create-block/kurage-worker",
"version": "0.1.0",
"title": "Kurage Worker",
"category": "widgets",
"icon": "smiley",
"description": "Example block scaffolded with Create Block tool.",
"supports": {
"html": false
},
"attributes": {
"message": {
"type": "string",
"default": ""
}
},
"textdomain": "kurage-worker",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
edit.tsx
でmessage
属性を編集出来るよう設定。
import React from 'react';
import { useBlockProps } from '@wordpress/block-editor';
import { BlockEditProps } from '@wordpress/blocks';
import KurageExampleBlockProps from './props';
import './editor.scss';
import { TextControl } from '@wordpress/components';
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const cc = useBlockProps();
const { message } = props.attributes;
const { setAttributes } = props;
return (
<div {...cc}>
メッセージ:
<TextControl
value={message}
onChange={v => setAttributes({ message: v })}
/>
</div>
);
}
index.tsx
とprops
も編集。
propsの型にmessage
の追加と、オプションにattributes
の追加を行う。
export default interface KurageExampleBlockProps
{
message: string;
}
import { BlockConfiguration, registerBlockType } from '@wordpress/blocks';
import Edit from './edit';
import save from './save';
import metadata from './block.json';
import KurageExampleBlockProps from './props';
import './style.scss';
// 第二引数の型、ジェネリックの引数にはpropsの型を指定
const blockConf: BlockConfiguration<KurageExampleBlockProps> =
{
attributes: metadata.attributes as any,
title: metadata.title,
category: metadata.category,
edit: Edit,
save //: props => null,
};
registerBlockType(metadata.name, blockConf);
今回attributes
の設定をblock.json
の方に書いたのでそれを引っ張ってくる。
kurage-worker.php
function create_block_kurage_worker_block_init() {
register_block_type(
__DIR__ . '/build',
[
'render_callback' => function($attr, $content)
{
return "Message: {$attr["message"]}";
}
]
);
}
PHP側も変更。
$attr
からmessage
属性を取得出来ます。
結果を見てみましょう。
編集ページ
プレビュー
属性を利用し、例えばPostのIDを渡すようにしてサーバー上でその投稿をレンダリングしたり出来ます。
the_post()
などその場で出力してしまうような関数はバッファリングしてから返すように工夫する必要があります。
編集側でもサーバーサイドレンダリング
さっきはフロント(プレビュー)側での表示でした。
今度は編集側でサーバーサイドレンダリングする方法です。
実はそれ用のコンポーネントが存在します。
その名もServerSideRender
です。
ServerSideRenderを使用するには以下をインストールします。
npm install --save @wordpress/server-side-render
edit.tsx
import React from 'react';
import { useBlockProps } from '@wordpress/block-editor';
import { BlockEditProps } from '@wordpress/blocks';
import ServerSideRender from '@wordpress/server-side-render';
import KurageExampleBlockProps from './props';
import './editor.scss';
import { TextControl } from '@wordpress/components';
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const cc = useBlockProps();
const { message } = props.attributes;
const { setAttributes } = props;
return (
<div {...cc}>
メッセージ:
<TextControl
value={message}
onChange={v => setAttributes({ message: v })}
/>
<p>↓プレビュー</p>
<ServerSideRender
block="create-block/kurage-worker"
attributes={ {message} }
/>
</div>
);
}
入力するとサーバーサイドレンダリングされた結果が表示されます。
連続で入力すると頻繁にサーバー(render_callback)
にアクセスがあります。
読み込み中の確認
気づきにくい読み込み中の処理は既に備わってます。
kurage-worker.php
の一部を変更します。
function create_block_kurage_worker_block_init() {
register_block_type(
__DIR__ . '/build',
[
'render_callback' => function($attr, $content)
{
sleep(3);
return "Message: {$attr["message"]}";
}
]
);
}
add_action( 'init', 'create_block_kurage_worker_block_init' );
sleep(3)
でサーバーサイドでの処理を3秒間止めてみました。
デフォルトでの読み込み中の処理です。
Spinner
が表示されていることが確認出来ます。
ServerSideRender
のLoadingResponsePlaceholder
を使って上書出来るのですが興味ある方はソースコードを見て参考にしてみてください。