登録

WordPressのブロックは、通常、block.jsonメタデータを使用してサーバー側とクライアント側の両方で登録されます。以下のフィルターを使用して、PHPでサーバー上での登録中やJavaScriptでクライアント上でのブロック設定を変更または拡張できます。詳細については、ブロック登録ガイドを参照してください。

block_type_metadata

サーバー上でPHPを使用してブロックタイプを登録する際に、block.jsonファイルから読み込まれた生のメタデータをフィルタリングします。メタデータが処理される前に変更を適用できます。

このフィルターのコールバック関数は、1つのパラメーターを受け取ります:

  • $metadata (array): ブロックタイプを登録するためにblock.jsonから読み込まれたメタデータ。

以下の例では、すべてのブロックのapiVersion2に設定します。

  1. function example_filter_metadata_registration( $metadata ) {
  2. $metadata['apiVersion'] = 2;
  3. return $metadata;
  4. };
  5. add_filter( 'block_type_metadata', 'example_filter_metadata_registration' );

ここでは、見出しブロックの背景色とグラデーションサポートを無効にするより堅牢な例を示します。block_type_metadataフィルターは、エディター体験のキュレーションに最適です。

  1. function example_disable_heading_background_color_and_gradients( $metadata ) {
  2. // Only apply the filter to Heading blocks.
  3. if ( ! isset( $metadata['name'] ) || 'core/heading' !== $metadata['name'] ) {
  4. return $metadata;
  5. }
  6. // Check if 'supports' key exists.
  7. if ( isset( $metadata['supports'] ) && isset( $metadata['supports']['color'] ) ) {
  8. // Remove Background color and Gradients support.
  9. $metadata['supports']['color']['background'] = false;
  10. $metadata['supports']['color']['gradients'] = false;
  11. }
  12. return $metadata;
  13. }
  14. add_filter( 'block_type_metadata', 'example_disable_heading_background_color_and_gradients' );

block_type_metadata_settings

処理されたブロックタイプメタデータから決定された設定をフィルタリングします。デフォルトで処理されないブロックメタデータを使用してカスタム変更を適用できます。

このフィルターのコールバック関数は、2つのパラメーターを受け取ります:

  • $settings (array): ブロックタイプを登録するための決定された設定の配列。
  • $metadata (array): block.jsonファイルから読み込まれたメタデータ。

以下の例では、すべてのブロックのapiVersion1だけ増加させます。

  1. function example_filter_metadata_registration( $settings, $metadata ) {
  2. $settings['api_version'] = $metadata['apiVersion'] + 1;
  3. return $settings;
  4. };
  5. add_filter( 'block_type_metadata_settings', 'example_filter_metadata_registration', 10, 2 );

register_block_type_args

ブロックタイプがサーバー上で正式に登録される直前に、ブロックの引数配列($args)をフィルタリングします。

このフィルターのコールバック関数は、2つのパラメーターを受け取ります:

  • $args (array): ブロックタイプを登録するための引数の配列。
  • $block_type (string): 名前空間を含むブロックタイプ名。
  1. 以下のコードは、段落、見出し、リスト、およびリストアイテムブロックの色のコントロールを無効にします。
  2. ``````bash
  3. function example_disable_color_for_specific_blocks( $args, $block_type ) {
  4. // List of block types to modify.
  5. $block_types_to_modify = [
  6. 'core/paragraph',
  7. 'core/heading',
  8. 'core/list',
  9. 'core/list-item'
  10. ];
  11. // Check if the current block type is in the list.
  12. if ( in_array( $block_type, $block_types_to_modify, true ) ) {
  13. // Disable color controls.
  14. $args['supports']['color'] = array(
  15. 'text' => false,
  16. 'background' => false,
  17. 'link' => false,
  18. );
  19. }
  20. return $args;
  21. }
  22. add_filter( 'register_block_type_args', 'example_disable_color_for_specific_blocks', 10, 2 );
  23. `

blocks.registerBlockType

JavaScriptを使用してクライアントでブロックを登録する際に、ブロック設定をフィルタリングするために使用されます。ブロック設定、登録されたブロックの名前、およびnullまたは非推奨のブロック設定(登録された非推奨に適用される場合)を引数として受け取ります。このフィルターは、ブロックの非推奨設定のそれぞれにも適用されます。

以下の例では、リストブロックが標準生成クラス名(wp-block-list)で保存されることを保証します:

  1. function addListBlockClassName( settings, name ) {
  2. if ( name !== 'core/list' ) {
  3. return settings;
  4. }
  5. return {
  6. ...settings,
  7. supports: {
  8. ...settings.supports,
  9. className: true,
  10. },
  11. };
  12. }
  13. wp.hooks.addFilter(
  14. 'blocks.registerBlockType',
  15. 'my-plugin/class-names/list-block',
  16. addListBlockClassName
  17. );

フロントエンド

フロントエンドでブロックの出力を変更するために利用できるPHPフィルターは次のとおりです。

render_block

任意のブロックのフロントエンドコンテンツをフィルタリングします。このフィルターは、エディター内のブロックの動作には影響しません。

このフィルターのコールバック関数は、3つのパラメーターを受け取ります:

  • $block_content (string): ブロックコンテンツ。
  • $block (array): 名前と属性を含む完全なブロック。
  • $instance (WP_Block): ブロックインスタンス。

以下の例では、クラスexample-classがフロントエンドのすべての段落ブロックに追加されます。ここでは、HTML APIを使用して、正規表現に依存せずにクラスを簡単に追加します。

  1. function example_add_custom_class_to_paragraph_block( $block_content, $block ) {
  2. // Check if the block is a Paragraph block.
  3. if ( 'core/paragraph' === $block['blockName'] ) {
  4. // Add the custom class to the block content using the HTML API.
  5. $processor = new WP_HTML_Tag_Processor( $block_content );
  6. if ( $processor->next_tag( 'p' ) ) {
  7. $processor->add_class( 'example-class' );
  8. }
  9. return $processor->get_updated_html();
  10. }
  11. return $block_content;
  12. }
  13. add_filter( 'render_block', 'example_add_custom_class_to_paragraph_block', 10, 2 );

renderblock{namespace/block}

定義されたブロックのフロントエンドコンテンツをフィルタリングします。これは、特定のブロックタイプを変更する必要がある場合のrender_blockの単純な形式です。

このフィルターのコールバック関数は、3つのパラメーターを受け取ります:

  • $block_content (string): ブロックコンテンツ。
  • $block (array): 名前と属性を含む完全なブロック。
  • $instance (WP_Block): ブロックインスタンス。

以下の例では、クラスexample-classがフロントエンドのすべての段落ブロックに追加されます。上記のrender_blockの例と比較して、コンテンツを変更する前にブロックタイプを確認する必要がなくなります。再度、HTML APIが正規表現の代わりに使用されます。

  1. function example_add_custom_class_to_paragraph_block( $block_content, $block ) {
  2. // Add the custom class to the block content using the HTML API.
  3. $processor = new WP_HTML_Tag_Processor( $block_content );
  4. if ( $processor->next_tag( 'p' ) ) {
  5. $processor->add_class( 'example-class' );
  6. }
  7. return $processor->get_updated_html();
  8. }
  9. add_filter( 'render_block_core/paragraph', 'example_add_custom_class_to_paragraph_block', 10, 2 );

エディター

エディターで編集中のブロックの動作を変更するために利用できるJavaScriptフィルターは次のとおりです。

blocks.getSaveElement

ブロックのsave関数の結果に適用されるフィルターです。このフィルターは、要素を置き換えたり拡張したりするために使用されます。たとえば、React.cloneElementを使用して要素のプロパティを変更したり、子要素を置き換えたり、まったく新しい要素を返したりします。

このフィルターのコールバック関数は、3つのパラメーターを受け取ります:

  • element (Object): 修正されて返される要素。
  • blockType (Object): ブロックタイプ定義オブジェクト。
  • attributes (Object): ブロックの属性。

以下の例では、カバー ブロックを外部コンテナdivでラップします。

  1. function wrapCoverBlockInContainer( element, blockType, attributes ) {
  2. // Skip if element is undefined.
  3. if ( ! element ) {
  4. return;
  5. }
  6. // Only apply to Cover blocks.
  7. if ( blockType.name !== 'core/cover' ) {
  8. return element;
  9. }
  10. // Return the element wrapped in a div.
  11. return <div className="cover-block-wrapper">{ element }</div>;
  12. }
  13. wp.hooks.addFilter(
  14. 'blocks.getSaveElement',
  15. 'my-plugin/wrap-cover-block-in-container',
  16. wrapCoverBlockInContainer
  17. );

blocks.getSaveContent.extraProps

  1. このフィルターのコールバック関数は、3つのパラメーターを受け取ります:
  2. - `````props````` (`````Object`````): 修正されて返される現在の`````save`````要素のプロパティ。
  3. - `````blockType````` (`````Object`````): ブロックタイプ定義オブジェクト。
  4. - `````attributes````` (`````Object`````): ブロックの属性。
  5. 以下の例では、すべてのブロックにデフォルトで赤い背景を追加します。
  6. ``````bash
  7. function addBackgroundColorStyle( props ) {
  8. return {
  9. ...props,
  10. style: { backgroundColor: 'red' },
  11. };
  12. }
  13. wp.hooks.addFilter(
  14. 'blocks.getSaveContent.extraProps',
  15. 'my-plugin/add-background-color-style',
  16. addBackgroundColorStyle
  17. );
  18. `

注意: このフィルターが次回投稿が編集されるときに既存のコンテンツを変更すると、ブロック検証エラーが発生します。エディターは、投稿に保存されたコンテンツがsave()関数によって出力されたコンテンツと一致することを確認します。

この検証エラーを回避するには、render_blockをサーバー側で使用して、既存の投稿コンテンツをこのフィルターの代わりに変更します。render_blockドキュメントを参照してください。

blocks.getBlockDefaultClassName

ブロックの生成されたHTMLクラスは、wp-block-{name}命名法に従います。このフィルターを使用すると、代替のクラス名を提供できます。

  1. // Our filter function.
  2. function setBlockCustomClassName( className, blockName ) {
  3. return blockName === 'core/code' ? 'my-plugin-code' : className;
  4. }
  5. // Adding the filter.
  6. wp.hooks.addFilter(
  7. 'blocks.getBlockDefaultClassName',
  8. 'my-plugin/set-block-custom-class-name',
  9. setBlockCustomClassName
  10. );

blocks.switchToBlockType.transformedBlock

ブロック変換からの個々の変換結果をフィルタリングするために使用されます。変換は多対多であり、1対1ではないため、すべての元のブロックが渡されます。

blocks.getBlockAttributes

ブロックの属性のデフォルト解析の直後に呼び出され、検証の前にプラグインが属性値を操作できるようにします。

このフィルターのコールバック関数は、4つのパラメーターを受け取ります:

blockAttributes (Object): すべてのブロック属性。

blockType (Object): ブロックタイプ。

innerHTML (string): 生のブロックコンテンツ。

attributes (object): 既知のブロック属性(区切り記号から)。

以下の例では、blocks.getBlockAttributesフィルターを使用して、ページ上のすべての段落ブロックの位置をロックします。

  1. // Our filter function
  2. function lockParagraphs( blockAttributes, blockType, innerHTML, attributes ) {
  3. if('core/paragraph' === blockType.name) {
  4. blockAttributes['lock'] = {move: true}
  5. }
  6. return blockAttributes;
  7. }
  8. // Add the filter
  9. wp.hooks.addFilter(
  10. 'blocks.getBlockAttributes',
  11. 'my-plugin/lock-paragraphs',
  12. lockParagraphs
  13. );

editor.BlockEdit

ブロックのeditコンポーネントを変更するために使用されます。元のブロックBlockEditコンポーネントを受け取り、新しいラップされたコンポーネントを返します。

以下の例では、すべてのブロックに新しいインスペクターパネルを追加します。

  1. const { createHigherOrderComponent } = wp.compose;
  2. const { InspectorControls } = wp.blockEditor;
  3. const { PanelBody } = wp.components;
  4. const withMyPluginControls = createHigherOrderComponent( ( BlockEdit ) => {
  5. return ( props ) => {
  6. return (
  7. <>
  8. <BlockEdit key="edit" { ...props } />
  9. <InspectorControls>
  10. <PanelBody>My custom control</PanelBody>
  11. </InspectorControls>
  12. </>
  13. );
  14. };
  15. }, 'withMyPluginControls' );
  16. wp.hooks.addFilter(
  17. 'editor.BlockEdit',
  18. 'my-plugin/with-inspector-controls',
  19. withMyPluginControls
  20. );

このフックはすべてのブロックに対して実行されるため、消費することでパフォーマンスの回帰が発生する可能性があります。特にブロック選択メトリックに関してです。

これを軽減するために、実行する作業が特定の条件下でのみ実行されるように変更できるかどうかを検討してください。

たとえば、ブロックが選択されたときにのみレンダリングする必要があるコンポーネントを追加しているとします。この場合、ブロックの「選択された」状態(props.isSelected)を使用してレンダリングを条件付けできます。

以下の例では、すべてのブロックに新しいインスペクターパネルを追加しますが、ブロックが選択されているときのみです。

  1. const withMyPluginControls = createHigherOrderComponent( ( BlockEdit ) => {
  2. return ( props ) => {
  3. return (
  4. <>
  5. <BlockEdit { ...props } />
  6. { props.isSelected && (
  7. <InspectorControls>
  8. <PanelBody>My custom control</PanelBody>
  9. </InspectorControls>
  10. ) }
  11. </>
  12. );
  13. };
  14. }, 'withMyPluginControls' );

editor.BlockListBlock

ブロックのeditコンポーネントとすべてのツールバーを含むブロックのラッパーコンポーネントを変更するために使用されます。元のBlockListBlockコンポーネントを受け取り、新しいラップされたコンポーネントを返します。

以下の例では、すべてのブロックにユニークなクラス名を追加します。

  1. const { createHigherOrderComponent } = wp.compose;
  2. const withClientIdClassName = createHigherOrderComponent(
  3. ( BlockListBlock ) => {
  4. return ( props ) => {
  5. return (
  6. <BlockListBlock
  7. { ...props }
  8. className={ 'block-' + props.clientId }
  9. />
  10. );
  11. };
  12. },
  13. 'withClientIdClassName'
  14. );
  15. wp.hooks.addFilter(
  16. 'editor.BlockListBlock',
  17. 'my-plugin/with-client-id-class-name',
  18. withClientIdClassName
  19. );

ラップされたコンポーネントのwrapperPropsプロパティを使用して、ブロックのラッパーコンポーネントに新しいプロパティを追加できます。以下の例のように。

  1. const { createHigherOrderComponent } = wp.compose;
  2. const withMyWrapperProp = createHigherOrderComponent( ( BlockListBlock ) => {
  3. return ( props ) => {
  4. const wrapperProps = {
  5. ...props.wrapperProps,
  6. 'data-my-property': 'the-value',
  7. };
  8. return <BlockListBlock { ...props } wrapperProps={ wrapperProps } />;
  9. };
  10. }, 'withMyWrapperProp' );
  11. wp.hooks.addFilter(
  12. 'editor.BlockListBlock',
  13. 'my-plugin/with-my-wrapper-prop',
  14. withMyWrapperProp
  15. );

editor.postContentBlockTypes

ロックされたテンプレート内で使用されている場合でも、有効にする必要があるブロックのリストを変更するために使用されます。投稿にデータを保存するすべてのブロックは、ここに追加する必要があります。これの例は、投稿のフィーチャー画像ブロックです。テンプレートでよく使用されるこのブロックは、テンプレートがロックされている場合でも画像を選択できるようにする必要があります。

以下の例では、架空のブロックnamespace/exampleを有効にします。

  1. const addExampleBlockToPostContentBlockTypes = ( blockTypes ) => {
  2. return [ ...blockTypes, 'namespace/example' ];
  3. };
  4. wp.hooks.addFilter(
  5. 'editor.postContentBlockTypes',
  6. 'my-plugin/post-content-block-types',
  7. addExampleBlockToPostContentBlockTypes
  8. );

ブロックの削除

拒否リストの使用

ブロックを追加するのは簡単で、削除するのも同様です。プラグインやテーマの著者は、JavaScriptの拒否リストを使用してブロックを「登録解除」できます。

次のコードをmy-plugin.jsファイルに配置します。

  1. // my-plugin.js
  2. import { unregisterBlockType } from '@wordpress/blocks';
  3. import domReady from '@wordpress/dom-ready';
  4. domReady( function () {
  5. unregisterBlockType( 'core/verse' );
  6. } );

次に、次の関数を使用してエディターでこのスクリプトを読み込みます。

  1. <?php
  2. // my-plugin.php
  3. function my_plugin_deny_list_blocks() {
  4. wp_enqueue_script(
  5. 'my-plugin-deny-list-blocks',
  6. plugins_url( 'my-plugin.js', __FILE__ ),
  7. array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' )
  8. );
  9. }
  10. add_action( 'enqueue_block_editor_assets', 'my_plugin_deny_list_blocks' );

ブロックを登録解除する際には、どのコードが最初に実行されるかに競合条件が発生する可能性があります: ブロックを登録するか、ブロックを登録解除するか。登録解除コードが最後に実行されるようにしたいです。これを行うには、ブロックを登録しているコンポーネントを依存関係として指定する必要があります。この場合、wp-edit-postです。さらに、wp.domReady()を使用すると、DOMが読み込まれた後に登録解除コードが実行されることが保証されます。

許可リストの使用

許可リストを除いてすべてのブロックを無効にしたい場合は、上記のスクリプトを次のように適応できます:

  1. // my-plugin.js
  2. var allowedBlocks = [
  3. 'core/paragraph',
  4. 'core/image',
  5. 'core/html',
  6. 'core/freeform',
  7. ];
  8. wp.blocks.getBlockTypes().forEach( function ( blockType ) {
  9. if ( allowedBlocks.indexOf( blockType.name ) === -1 ) {
  10. wp.blocks.unregisterBlockType( blockType.name );
  11. }
  12. } );

挿入ツールからのブロックの非表示

allowed_block_types_all

WordPress 5.8以前は、このフックはallowed_block_typesとして知られており、現在は非推奨です。古いバージョンのWordPressをサポートする必要がある場合、どのフィルターを使用するかを検出する方法が必要になるかもしれません。allowed_block_typesが使用可能かどうかは、5.8で導入されたWP_Block_Editor_Contextクラスが存在するかどうかを確認することで確認できます。

サーバー上で、allowed_block_types_allフィルターを使用して挿入ツールに表示されるブロックのリストをフィルタリングできます。すべてのブロックタイプがサポートされている場合はtrue(すべてのブロックタイプがサポートされている)、false(ブロックタイプはサポートされていない)、または許可するブロックタイプ名の配列を返すことができます。また、提供された2番目のパラメーター$editor_contextを使用して、コンテンツに基づいてブロックタイプをフィルタリングできます。

  1. <?php
  2. // my-plugin.php
  3. function example_filter_allowed_block_types_when_post_provided( $allowed_block_types, $editor_context ) {
  4. if ( ! empty( $editor_context->post ) ) {
  5. return array( 'core/paragraph', 'core/heading' );
  6. }
  7. return $allowed_block_types;
  8. }
  9. add_filter( 'allowed_block_types_all', 'example_filter_allowed_block_types_when_post_provided', 10, 2 );

ブロックカテゴリの管理

block_categories_all

WordPress 5.8以前は、このフックはblock_categoriesとして知られており、現在は非推奨です。古いバージョンのWordPressをサポートする必要がある場合、どのフィルターを使用するかを検出する方法が必要になるかもしれません。block_categoriesが使用可能かどうかは、5.8で導入されたWP_Block_Editor_Contextクラスが存在するかどうかを確認することで確認できます。

  1. ``````bash
  2. // my-plugin.php
  3. function example_filter_block_categories_when_post_provided( $block_categories, $editor_context ) {
  4. if ( ! empty( $editor_context->post ) ) {
  5. array_push(
  6. $block_categories,
  7. array(
  8. 'slug' => 'custom-category',
  9. 'title' => __( 'Custom Category', 'custom-plugin' ),
  10. 'icon' => null,
  11. )
  12. );
  13. }
  14. return $block_categories;
  15. }
  16. add_filter( 'block_categories_all', 'example_filter_block_categories_when_post_provided', 10, 2 );
  17. `

wp.blocks.updateCategory

ブロックカテゴリにアイコンを表示するには、icon属性を設定します。値はWordPress Dashiconのスラッグにすることができます。

SVG形式のカスタムアイコンを設定することもできます。そのためには、アイコンをレンダリングしてフロントエンドに設定する必要があります。これにより、WordPress SVGを利用でき、モバイル互換性が向上し、アイコンがよりアクセスしやすくなります。

前の例で表示されたカテゴリのSVGアイコンを設定するには、次のJavaScriptコードをエディターに追加し、wp.blocks.updateCategoryを呼び出します。例えば:

  1. ( function () {
  2. var el = React.createElement;
  3. var SVG = wp.primitives.SVG;
  4. var circle = el( 'circle', {
  5. cx: 10,
  6. cy: 10,
  7. r: 10,
  8. fill: 'red',
  9. stroke: 'blue',
  10. strokeWidth: '10',
  11. } );
  12. var svgIcon = el(
  13. SVG,
  14. { width: 20, height: 20, viewBox: '0 0 20 20' },
  15. circle
  16. );
  17. wp.blocks.updateCategory( 'my-category', { icon: svgIcon } );
  18. } )();