概要

プラグインにサイドバーを追加する方法。サイドバーはエディターの最右端の領域です。プラグインは、InspectorControls(ギアアイコン)の隣に展開可能な追加のアイコンを追加できます。

例のサイドバー

注:このチュートリアルはカスタムサイドバーを扱っています。サイドバーにコントロールを追加したい場合は、ブロックツールバーと設定サイドバーを参照してください。

始める前に

このチュートリアルは、既存のプラグインセットアップがあり、PHPおよびJavaScriptコードを追加する準備ができていることを前提としています。WordPressプラグインの紹介と、ブロックエディターを拡張するためのJavaScriptの使用方法については、JavaScriptの始め方チュートリアルを参照してください。

ステップバイステップガイド

ステップ1:サイドバーを立ち上げる

最初のステップは、エディターに新しいプラグインが独自のサイドバーを持つことを伝えることです。registerPluginPluginSidebar、およびcreateElementユーティリティをそれぞれ@wordpress/plugins@wordpress/editorreactパッケージから使用します。

次のコードをplugin-sidebar.jsというJavaScriptファイルに追加し、プラグインのディレクトリ内に保存します:

  1. ( function ( wp, React ) {
  2. var el = React.createElement;
  3. var registerPlugin = wp.plugins.registerPlugin;
  4. var PluginSidebar = wp.editor.PluginSidebar;
  5. registerPlugin( 'my-plugin-sidebar', {
  6. render: function () {
  7. return el(
  8. PluginSidebar,
  9. {
  10. name: 'my-plugin-sidebar',
  11. icon: 'admin-post',
  12. title: 'My plugin sidebar',
  13. },
  14. 'Meta field'
  15. );
  16. },
  17. } );
  18. } )( window.wp, window.React );

このコードが機能するためには、これらのユーティリティがブラウザで利用可能である必要があるため、wp-pluginswp-edit-post、およびreactをスクリプトの依存関係として指定する必要があります。

スクリプトを登録し、依存関係を指定するためのPHPコードは次のとおりです:

  1. <?php
  2. /*
  3. Plugin Name: Sidebar plugin
  4. */
  5. function sidebar_plugin_register() {
  6. wp_register_script(
  7. 'plugin-sidebar-js',
  8. plugins_url( 'plugin-sidebar.js', __FILE__ ),
  9. array( 'wp-plugins', 'wp-editor', 'react' )
  10. );
  11. }
  12. add_action( 'init', 'sidebar_plugin_register' );
  13. function sidebar_plugin_script_enqueue() {
  14. wp_enqueue_script( 'plugin-sidebar-js' );
  15. }
  16. add_action( 'enqueue_block_editor_assets', 'sidebar_plugin_script_enqueue' );

このプラグインをインストールして有効化すると、エディターの右上にタックに似た新しいアイコンが表示されます。それをクリックすると、プラグインのサイドバーが開きます:

サイドバーの立ち上げ

ステップ2:サイドバーのスタイルを調整し、コントロールを追加する

サイドバーが立ち上がったら、次のステップは必要なコンポーネントと基本的なスタイリングでそれを満たすことです。

メタフィールドの値を視覚化および編集するために、入力コンポーネントを使用します。@wordpress/componentsパッケージには再利用可能な多くのコンポーネントが含まれており、特にTextControlは入力フィールドを作成することを目的としています:

  1. ( function ( wp ) {
  2. var el = React.createElement;
  3. var registerPlugin = wp.plugins.registerPlugin;
  4. var PluginSidebar = wp.editor.PluginSidebar;
  5. var TextControl = wp.components.TextControl;
  6. registerPlugin( 'my-plugin-sidebar', {
  7. render: function () {
  8. return el(
  9. PluginSidebar,
  10. {
  11. name: 'my-plugin-sidebar',
  12. icon: 'admin-post',
  13. title: 'My plugin sidebar',
  14. },
  15. el(
  16. 'div',
  17. { className: 'plugin-sidebar-content' },
  18. el( TextControl, {
  19. label: 'Meta Block Field',
  20. value: 'Initial value',
  21. onChange: function ( content ) {
  22. console.log( 'content changed to ', content );
  23. },
  24. } )
  25. )
  26. );
  27. },
  28. } );
  29. } )( window.wp );

この新しいコードでplugin-sidebar.jsを更新します。新しいユーティリティwp.components@wordpress/componentsパッケージから使用されていることに注意してください。PHPファイルのwp_register_script関数の依存関係にwp-componentsを追加することを忘れないでください。

このコードは次のことを導入します:

  • スタイルをターゲットにするためにplugin-sidebar-content CSSクラスをdiv要素に追加、
  • プレーンな'Meta field'テキストの代わりにTextControlコンポーネントを使用します。

新しいCSSクラスが利用可能になったので、少しスタイルを追加できます。プラグインディレクトリ内にplugin-sidebar.cssという新しいファイルを作成し、次のようにパディングを追加します:

  1. .plugin-sidebar-content {
  2. padding: 16px;
  3. }

スクリプトを登録し、JavaScriptファイルとともにenqueue_block_editor_assetsで読み込むようにキューに追加します。

これらの変更の後、PHPコードは次のようになります:

  1. <?php
  2. /*
  3. Plugin Name: Sidebar example
  4. */
  5. function sidebar_plugin_register() {
  6. wp_register_script(
  7. 'plugin-sidebar-js',
  8. plugins_url( 'plugin-sidebar.js', __FILE__ ),
  9. array(
  10. 'react',
  11. 'wp-plugins',
  12. 'wp-editor',
  13. 'wp-components'
  14. )
  15. );
  16. wp_register_style(
  17. 'plugin-sidebar-css',
  18. plugins_url( 'plugin-sidebar.css', __FILE__ )
  19. );
  20. }
  21. add_action( 'init', 'sidebar_plugin_register' );
  22. function sidebar_plugin_script_enqueue() {
  23. wp_enqueue_script( 'plugin-sidebar-js' );
  24. wp_enqueue_style( 'plugin-sidebar-css' );
  25. }
  26. add_action( 'enqueue_block_editor_assets', 'sidebar_plugin_script_enqueue' );

エディターを再読み込みし、サイドバーを開きます:

スタイルとコントロールのあるサイドバー

このコードはまだユーザーがデータを保存または取得することを許可していないため、次のステップではメタブロックフィールドに接続する方法に焦点を当てます。

ステップ3:メタフィールドを登録する

確認するために、ブロックエディターストアをクエリしてフィールドが読み込まれているか確認します。実装後、エディターページを再読み込みし、ブラウザの開発者コンソールを開きます。このJavaScriptスニペットをコンソールで使用して確認します:

  1. wp.data.select( 'core/editor' ).getCurrentPost().meta;

この関数は、登録したメタフィールドを含むオブジェクトを返します。

コードがundefinedを返す場合は、投稿タイプがcustom-fieldsをサポートしていることを確認してください。投稿を登録する際またはadd_post_type_support関数で行います。

ステップ4:入力コントロールを初期化する

エディターストアにフィールドが利用可能になったので、UIに表示できるようになります。機能を追加する際にコードをクリーンに保つために、入力コントロールを関数に抽出します。

  1. ( function ( wp ) {
  2. var el = React.createElement;
  3. var registerPlugin = wp.plugins.registerPlugin;
  4. var PluginSidebar = wp.editor.PluginSidebar;
  5. var TextControl = wp.components.TextControl;
  6. var MetaBlockField = function () {
  7. return el( TextControl, {
  8. label: 'Meta Block Field',
  9. value: 'Initial value',
  10. onChange: function ( content ) {
  11. console.log( 'content changed to ', content );
  12. },
  13. } );
  14. };
  15. registerPlugin( 'my-plugin-sidebar', {
  16. render: function () {
  17. return el(
  18. PluginSidebar,
  19. {
  20. name: 'my-plugin-sidebar',
  21. icon: 'admin-post',
  22. title: 'My plugin sidebar',
  23. },
  24. el(
  25. 'div',
  26. { className: 'plugin-sidebar-content' },
  27. el( MetaBlockField )
  28. )
  29. );
  30. },
  31. } );
  32. } )( window.wp );
  1. `````useSelect`````関数は、コンポーネントが読み込まれるときにデータを取得し、データが変更された場合に更新します。`````useSelect`````を使用したコードの更新は次のとおりです:
  2. ``````bash
  3. ( function ( wp ) {
  4. var el = React.createElement;
  5. var registerPlugin = wp.plugins.registerPlugin;
  6. var PluginSidebar = wp.editor.PluginSidebar;
  7. var Text = wp.components.TextControl;
  8. var useSelect = wp.data.useSelect;
  9. var MetaBlockField = function () {
  10. var metaFieldValue = useSelect( function ( select ) {
  11. return select( 'core/editor' ).getEditedPostAttribute(
  12. 'meta'
  13. )[ 'sidebar_plugin_meta_block_field' ];
  14. }, [] );
  15. return el( Text, {
  16. label: 'Meta Block Field',
  17. value: metaFieldValue,
  18. onChange: function ( content ) {
  19. console.log( 'content has changed to ', content );
  20. },
  21. } );
  22. };
  23. registerPlugin( 'my-plugin-sidebar', {
  24. render: function () {
  25. return el(
  26. PluginSidebar,
  27. {
  28. name: 'my-plugin-sidebar',
  29. icon: 'admin-post',
  30. title: 'My plugin sidebar',
  31. },
  32. el(
  33. 'div',
  34. { className: 'plugin-sidebar-content' },
  35. el( MetaBlockField )
  36. )
  37. );
  38. },
  39. } );
  40. } )( window.wp );
  41. `
  1. 注:`````getEditedPostAttribute`````呼び出しは、ユーザーがまだ保存していない編集を含む投稿の最新の値を取得するために使用されます。
  2. コードを更新し、再読み込みし、サイドバーを開くことで動作を確認します。入力の内容はもはや`````Initial value`````ではなく、空の文字列です。ユーザーはまだ値を入力できませんが、ストア内の値が変更された場合にコンポーネントが更新されることを確認できます。ブラウザのコンソールを開き、実行します:
  3. ``````bash
  4. wp.data
  5. .dispatch( 'core/editor' )
  6. .editPost( { meta: { sidebar_plugin_meta_block_field: 'hello world!' } } );
  7. `

入力コンポーネントの内容が変化するのを観察できます。

ステップ5:入力の内容が変更されたときにメタフィールドを更新する

最後のステップは、入力内容が変更されたときにメタフィールドを更新することです。

  1. ``````bash
  2. ( function ( wp ) {
  3. var el = React.createElement;
  4. var registerPlugin = wp.plugins.registerPlugin;
  5. var PluginSidebar = wp.editor.PluginSidebar;
  6. var TextControl = wp.components.TextControl;
  7. var useSelect = wp.data.useSelect;
  8. var useDispatch = wp.data.useDispatch;
  9. var MetaBlockField = function ( props ) {
  10. var metaFieldValue = useSelect( function ( select ) {
  11. return select( 'core/editor' ).getEditedPostAttribute(
  12. 'meta'
  13. )[ 'sidebar_plugin_meta_block_field' ];
  14. }, [] );
  15. var editPost = useDispatch( 'core/editor' ).editPost;
  16. return el( TextControl, {
  17. label: 'Meta Block Field',
  18. value: metaFieldValue,
  19. onChange: function ( content ) {
  20. editPost( {
  21. meta: { sidebar_plugin_meta_block_field: content },
  22. } );
  23. },
  24. } );
  25. };
  26. registerPlugin( 'my-plugin-sidebar', {
  27. render: function () {
  28. return el(
  29. PluginSidebar,
  30. {
  31. name: 'my-plugin-sidebar',
  32. icon: 'admin-post',
  33. title: 'My plugin sidebar',
  34. },
  35. el(
  36. 'div',
  37. { className: 'plugin-sidebar-content' },
  38. el( MetaBlockField )
  39. )
  40. );
  41. },
  42. } );
  43. } )( window.wp );
  44. `

更新後、ユーザーが入力すると、入力コントロールはeditPostを呼び出し、各キー入力でエディターストアを更新します。

JavaScriptを更新し、サイドバーを読み込み、入力フィールドに入力します。入力コントロールに何かを入力し、ブラウザの開発者コンソールでJavaScriptスニペットを実行することで、保存されていることを確認できます:

  1. wp.data.select( 'core/editor' ).getEditedPostAttribute( 'meta' )[
  2. 'sidebar_plugin_meta_block_field'
  3. ];

表示されるメッセージは、入力した内容であるべきです。

投稿を保存すると、保存後に再読み込みし、入力コントロールが最後に入力した値で初期化されていることを確認することで、データベースに正しく保存されていることを確認できます。

追加リソース

@wordpress/dataパッケージで作業するためのドキュメント。

このガイドで使用される関数:

結論

これで、post_metaの内容を更新するために使用できるカスタムサイドバーができました。

完全な例が利用可能です。plugin-sidebarの例block-development-examplesリポジトリからダウンロードしてください。

注意

エディターの「設定」ページの「パネル」でカスタムフィールドを有効にしている場合(右上の三点リーダーを介して)、この場合sidebar_plugin_meta_block_fieldと同じ名前のフィールドがエディタウィンドウの下部にあるカスタムフィールドパネルにも表示されます。これらの2つのフィールドは同じメタプロパティにアクセスできます。

テキストコントロールとカスタムフィールド

投稿を保存すると、TextControlの値が最初に保存され、カスタムフィールドの値が2番目に保存されるため、最終的にデータベースに永続化されるのはカスタムフィールドの値です。したがって、TextControlの値を変更しても、最終的に保存されるのはカスタムフィールドの値です。

カスタムフィールドが有効になっていない場合、この問題は発生しません。

カスタムフィールドを有効にし、サイドバーに投稿メタを持たせる必要がある場合、2つの解決策があります:

  • 1. メタフィールドの名前の前にアンダースコアを付けると、上記の例では_sidebar_plugin_meta_block_fieldになります。これは、投稿メタがプライベートとして扱われるべきであることを示し、投稿のカスタムフィールドセクションには表示されません。この解決策では、投稿を保存するとエラーが生成されますが、register_post_metaに渡されるargs配列にauth_callbackプロパティを追加し、最終的にtrueを返す関数を追加することで解決できます。詳細については、argsページのドキュメントを参照してください。
  • 2. TextControlのonChange関数で、Valueフィールドのテキストエリアをターゲットにし、そこにTextControlメタフィールドの値と同じ値を設定します。これにより、両方の場所で値が同じになり、TextControlで値が変更されると、データベースに保存されることが保証されます。
  1. return el( TextControl, {
  2. label: 'Meta Block Field',
  3. value: metaFieldValue,
  4. onChange: function ( content ) {
  5. editPost( {
  6. meta: { sidebar_plugin_meta_block_field: content }
  7. })
  8. document.querySelector( {the-value-textarea} ).innerHTML = content;
  9. },
  10. } );