WordPressのGutenbergのハンドブックやGitHubの内容などを参考にして、求める機能の実装を試した内容です。
注意点
- Gutenbergがコアに入る前の段階の記事です
- 書き方だけではなく、語句や名称にも問題がある可能性があります
- 内容が正確だと保証できないため、読む方は参考程度に考えてください
実現したいこと
- ショートコードのような用途で使えるGutenbergでブロックを作る
- サーバサイドレンダリングを試す
切っ掛けは参考にしたページで以下のように書かれていたためです。
要は編集画面上で検索とかサーバーサイドの処理が絡むようなものをプレビューしながら編集できるわけです。
render_callbackとServerSideRenderを使ったブロックの仕組みはショートコードの後継となるものと思われます。
ショートコードがなくなる話は見ていないので大丈夫だとは思いますが(なくなるという情報はないですよね…?)、後継とまで書かれるなら試しておいた方がよいかと。
ハンドブックや参考にしたGitHubのページは以下の通りです。
サンプルコード1
<div><p>ブロックで入力した内容</p></div>
一例目は基本として、上記のように単にブロックで入力した内容をpタグにいれただけのサンプルとなります。
入力欄の下にはサーバーから帰って来た値(前述のHTML)が出力されます。サンプルではCSSを当てていない状態なので単に同じ文字列が表示されているだけになりますが、入力内容に反応して表示が変わることを確認できます。
まずはJS側。
const { registerBlockType } = wp.blocks;
const { Fragment } = wp.element;
const { TextControl } = wp.components;
const { ServerSideRender } = wp.editor;
registerBlockType( 'my-plugin/test-as-shortcode-text', {
title: 'test-as-shortcode-text',
icon: 'universal-access-alt',
category: 'layout',
attributes: {
content: {
type: 'string'
},
},
edit( {attributes, setAttributes} ) {
const { content } = attributes;
const onChangeContent = newContent => {
setAttributes( { content: newContent } );
};
return(
<Fragment>
<TextControl
onChange={onChangeContent}
value={content}
/>
//ブロック内でサーバーでの処理(PHP側での処理)を表示する必要がない場合は、ServerSideRenderは削除しても可
<ServerSideRender
block='my-plugin/test-as-shortcode-text'
attributes={ attributes }
/>
</Fragment>
);
},
save() {
return null;
}
} );
続いてPHP側(プラグインの形ならプラグイン内のPHPファイル)。
//初期設定
add_action( 'enqueue_block_editor_assets', function() {
wp_enqueue_script(
'myplugin-gutenberge',
plugins_url( 'block.js', __FILE__ ),
[ 'wp-blocks', 'wp-element', 'wp-components', 'wp-editor' ]
);
} );
//今回用の設定
register_block_type( 'my-plugin/test-as-shortcode-text', array(
'attributes' => array(
'content' => array (
'type' => 'string'
)
),
'render_callback' => 'my_textbox_text',
) );
function my_textbox_text($attributes){
$html = '';
$html .= '<div class="my_textbox">';
$html .= '<p>' . esc_html($attributes['content']) . '</p>';
$html .= '</div>';
return $html;
}
ブロック読み込みエラー
個人的に詰まったのがregister_block_typeのattributesでtypeを記載しないとエラーになったことです。
attributesのみやcontentを加えただけではブロック内に以下のようなエラーがでます。
ブロック読み込みエラー: 無効なパラメーター: attributes
基本的には、JS側のregisterBlockTypeのattributesに記述した内容をそのまま持ってくる位の感じの方が良いかもしれません(必ずしもそうとは言い切れませんが)。
サンプル2
<!-- idにはカテゴリーID。numには表示件数。この2つをいれてカテゴリーの一覧を表示させるショートコード -->
[catlist id="" num=""]
続いて、上記のようなショートコードと同じようなものをブロックで作成します。
表示件数やIDはInspector(サイドバー)で変更する構造も考えましたが、とりあえずショーコードと多少は近い形にしやすいようにinputタグを使っています。
なお、今回は上記のショートコードで動かすように以前に作成したコードを流用しているため、PHP側の方は一例程度にご覧下さい(色々作り方は試している中の1つなので、これがいいとはいえません)。
まずはJS側。
const { registerBlockType } = wp.blocks;
const { Fragment } = wp.element;
const { ServerSideRender } = wp.editor;
registerBlockType( 'my-plugin/test-severside-as-shortcode-input', {
title: 'test-severside-as-shortcode-input',
icon: 'universal-access-alt',
category: 'layout',
attributes: {
id: {
type: 'integer',
default: '1',
},
num: {
type: 'integerg',
default: '10',
},
},
edit( {attributes, setAttributes} ) {
const { id, num } = attributes;
const onChangeInputId = newId => {
setAttributes( { id: newId.target.value } );
};
const onChangeInputNum = newNum => {
setAttributes( { num: newNum.target.value } );
};
return(
<Fragment>
<p>カテゴリーID:<input value={ id } onChange={ onChangeInputId } type="text" /></p>
<p>表示数:<input value={ num } onChange={ onChangeInputNum } type="text" />※初期値は10件表示</p>
<ServerSideRender
block='my-plugin/test-severside-as-shortcode-input'
attributes={ attributes }
/>
</Fragment>
);
},
save() {
return null;
}
} );
前述のようにカテゴリー一覧の記事用コードがまずあるため、それに合わせてdefalurtで未入力時の値を先に設定しています(カテゴリーIDは1/表示件数は10)。
初期値はPHP側でも設定可能だと思いますが、GutenbergはJS側で値を入れるため初期値もJS側で設定する方がよいと考えてこの形にしています。
後述するようにregister_block_typeの中とはいえPHPファイルにも記載しているので「JS側で設定する」という表現にそぐわない気はしますが。
続いてPHP側です。
//初期設定
add_action( 'enqueue_block_editor_assets', function() {
wp_enqueue_script(
'myplugin-gutenberge',
plugins_url( 'block.js', __FILE__ ),
[ 'wp-blocks', 'wp-element', 'wp-editor' ]
);
} );
//今回用の設定
register_block_type( 'my-plugin/test-severside-as-shortcode-input', array(
'attributes' => array(
'id' => array (
'type' => 'integer',
'default' => 1
),
'num' => array (
'type' => 'integer',
'default' => 10
),
),
'render_callback' => 'my_catlist_func',
) );
//カテゴリ一覧を表示させる
if(!function_exists('my_catlist_func')){
function my_catlist_func($attributes) {
$id = $attributes['id'];
$num = $attributes['num'];
$titlelist = new TitleList;
$html = $titlelist->get_cat_list($id,$num);
return $html;
}
}
//本筋から外れるため、カテゴリー表示用の記述は分けて後述します
typeをintegerにしているので、数値以外を入れるとブロック内に以下のエラーが出ます。
ブロック読み込みエラー: 無効なパラメーター: attributes
ただし、PHP側のtypeをstringにすると文字列でも動作してしまい意図しない状態になるため、typeは揃えた方が無難でしょう。
カテゴリー記事一覧のPHPサンプル
このGutenbergの関連記事表示用に作ったのものなのですが、今回のコードにもそのまま流用しているのが以下のものです(そのためタイトル順で並べる指定になっていたりしますが)。
「IDと表示件数を渡せば動作するコード」であれば何でもよいので当初は記載するつもりがなかったのですが、この辺を省くと不完全なサンプルになって分かりにくくなるかもしれないとも思われ、書くだけ書いておこうと記載している次第です。
class TitleList{
public function get_cat_list($catId ,$num){
$args = ''; //変数の初期化
$args = array(
'posts_per_page' => $num,
'cat' => $catId,
'orderby' => 'title',
'order' => 'ASC'
);
return $this->loop($args);
}
private function loop($args){
$html = '';
$current = ''; //現在表示中の記事ならクラスを出力
$currentId = get_the_ID();
$wp_query = new WP_Query($args);
if ( $wp_query->have_posts() ){
$html .= '<ul class="titlelist">';
while ( $wp_query->have_posts() ){
$wp_query->the_post();
$itemId = get_the_ID();
if($itemId === $currentId){
$current = ' <span>[現在表示中]</span>';
} else {
$current = '';
}
$html .= '<li class="titlelist_items"><a href="' . get_the_permalink() . '" title="' . the_title_attribute( 'echo=0' ) . '">' . get_the_title() . '</a>' . $current . '</li>';
}
$html .= '</ul>';
} else {
$html .= '<p>';
$html .= '申し訳ありませんが、現在このカテゴリーの記事はありません。';
$html .= '</p>';
}
wp_reset_query();
return $html;
}
}
結び
サーバーサイドの処理を含む場合、JSとPHPでどこをどう処理するのかの検討が重要になると思います。
また、入力欄の場所も検討事項です。
ブロック側で何らかの値を入力してServerSideRenderを動作させる場合、初期ブロックのアーカイブのように入力欄はサイドバーにあるのが筋かもしれません。
関連記事
Gutenberg(ブロックエディタ)に関連する記事一覧。
- [Gutenberg対応版]WordPressで複数のCSSをまとめてインラインCSSとして出力する
- @wordpress/create-blockで一つのプラグインに複数のブロックを入れる
- @wordpress/wp-env と @wordpress/create-block で簡単にブロック開発環境を作る
- 3度目のブロック開発環境(Docker Desktopとcreate-block)
- Gutenberg(ブロックエディタ)メモ
- Gutenberg(ブロックエディタ)メモ -Gutenbergの使い方で迷うところ
- Gutenberg(ブロックエディタ)メモ -ハンドブックでわからないところ1
- Gutenberg(ブロックエディタ)メモ -ハンドブックでわからないところ2
- Buttonを使う(MediaUploadとRichTextも含む)
- metaデータを設定する
- Templatesとplaceholderを使う
- Toggleを使う
- カスタムHTMLを使う
- サイドバー(Inspector)を設定する
- サイドバーを作ってcheckboxを使う
- サイドバーを作ってラジオボタンを使う
- ショートコードの代替案的なブロックを作る [現在表示中]
- ラジオボタンでクラスを変更可能なコードエディタブロックを作る
- 登録されているショートコードの一覧を表示したブロックを作る
- AddQuicktagのGutenberg対応に関して
- Classic Editorプラグインに関して
- wp_is_mobile関数を利用して出し分け機能をもったブロックを作る
- 任意のHTMLタグを範囲選択で挿入可能なツールバーを付ける
- 任意のHTMLタグを範囲選択で挿入可能なボタンをRichTextのツールバーに追加する
- 自動でテーマCSSの指定箇所をGutenberg用CSSとして用いる方法の検討
- 自動で出力されるブロック用のCSSを取除く
- Gutenberg関連の参考サイト:メモ
- WPのsetMeta()で複数のキーと値を保存する
- WPのブロックエディタでTypeError: Cannot read property ‘firstChild’ of nullのエラー:メモ
- WPのブロックエディタでUncaught Error: Minified React error #321のエラー:メモ
- WPのブロックエディタでタグをドロップダウンで変更する:メモ
- WPのブロックエディタでブロック追加用ボタンを表示させる:メモ
- WPのブロックエディタで親の値を子に設定する:メモ
- WPのブロック作成メモ
- WPの独自ブロックが設定されている時のみCSSやJSをフロントに表示する方法
- ブロック作成時のclassNameに関するメモ
- ブロック開発の環境構築におけるwp-scriptsとCreate Guten Blockのメモ
2人がこの記事を評価
役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。
連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。