Menu


@wordpress/components セレクトボックス SelectControl にカテゴリーやカスタムタクソノミーをセットする

2024年01月03日

WordPress ブロックエディタのオリジナルブロック開発、なかなか学習すべきことが多いですね。

私も日々学習し、少しずつ理解を進めています。

今日はタイトルに記載した通り、ブロックエディタのサイドバーのセレクトボックス( SelectControl )にカテゴリーやカスタムタクソノミーを動的にセットしたいということで、試したことを以下に記載します。

getEntityRecords でタクソノミーを取得

edit.js でカテゴリーの一覧は以下のようなコードで取得が可能です。

wp.data.select( 'core' ).getEntityRecords( 'taxonomy', 'category' )

カテゴリーの件数が多い場合は getEntityRecords の第三引数に query {per_page: -1} を入れてあげることで解決できますが、調べてみると {per_page: -1} を指定しても取得可能なカテゴリー数は( Rest-API の仕様上?)100個まで?の様子。

カテゴリーが100個以上ある場合にセレクトボックスで選択する UI というのはどうなんだろう?と思いながら、今回の私の環境では100個を超えるカテゴリーの WordPress 環境はなかったため、この話は一旦見て見ぬふりにします。

上記のコードは wp.data.select… と続けていますが、import { useSelect } from ‘@wordpress/data’ を宣伝して useSelect を使って取得する方法でもよさそうです。

const category = useSelect( ( select ) =>
	select( 'core' ).getEntityRecords( 'taxonomy', 'category' )
);

また、edit.js でカスタムタクソノミーの一覧を取得する場合は、getEntityRecords( ‘taxonomy’, ‘category’ ) の category 箇所をタクソノミースラッグにすれば OK です。

以下の例は、カスタムタクソノミー plan-cat を register_taxonomy にて登録していることを想定しています。

wp.data.select( 'core' ).getEntityRecords( 'taxonomy', 'plan-cat' )

カスタムタクソノミーを register_taxonomy にて登録する際、’show_in_rest’ => true を指定していないと Rest-API が有効とならず、上記コードを実行しても null が返ってきます。

私は ‘show_in_rest’ => true の記述をしていなかったため、getEntityRecords でカスタムタクソノミーが取得できない!!なんで!?と、数時間を過ごしました😅

‘show_in_rest’ => true はハマりポイントかもしれません。

セレクトボックス SelectControl にタクソノミーをセット

上記の内容を踏まえて、edit.js を以下のように記述し npm run build を実行、build フォルダに書き出されたブロックを読み込むと、セレクトボックスにカテゴリーやカスタムタクソノミーをセットすることができました。

import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
import {
	useBlockProps,
	InspectorControls
} from '@wordpress/block-editor';
import {
	SelectControl,
	PanelBody
} from '@wordpress/components';
 
export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();
	
	const {
		category_id,
		taxonomy_id
	} = attributes;
	
	const category = useSelect( ( select ) =>
		select( 'core' ).getEntityRecords( 'taxonomy', 'category' )
	);
	
	const category_options = [];
	category_options.push( {
		label: '選択してください',
		value: ''
	} );
	
	if ( category ) {
		for ( var i = 0; i < category.length; i++ ) {
			category_options.push( {
				label: category[i].name,
				value: category[i].id
			} );
		}
	}
  	
	const taxonomy = useSelect( ( select ) =>
		select( 'core' ).getEntityRecords( 'taxonomy', 'plan-cat', {per_page: -1, exclude:[23,24,25,26]} )
	);
  
	const taxonomy_options = [];
	taxonomy_options.push( {
		label: '選択してください',
		value: ''
	} );
	
	if ( taxonomy ) {
		for ( var i = 0; i < taxonomy.length; i++ ) {
			taxonomy_options.push( {
				label: taxonomy[i].name,
				value: taxonomy[i].id
	   		} );
		}
	}
	
	return (
    	<div { ...blockProps }>
    		<InspectorControls>
    			<PanelBody title={ __( 'カテゴリー', 'text-domain' ) } initialOpen="false">
			    	<SelectControl
						value = { category_id }
						options = { category_options }
						onChange = { ( value ) => {
							setAttributes({ category_id: value });
						}}
					/>
				</PanelBody>
				<PanelBody title={ __( 'カスタムタクソノミー', 'text-domain' ) } initialOpen="false">
         			<SelectControl
						value = { taxonomy_id }
						options = { taxonomy_options }
						onChange = { ( value ) => {
							setAttributes({ taxonomy_id: value });
						}}
					/>
				</PanelBody>
    		</InspectorControls>
    	</div>
	);
}
@wordpress/components SelectControl カテゴリーとカスタムタクソノミーをセット
@wordpress/components SelectControl カテゴリーを選択している図
@wordpress/components SelectControl カスタムタクソノミーを選択している図

WordPress に登録済みのカテゴリーとカスタムタクソノミーが、それぞれサイドバーに表示されていることがわかります。

getEntityRecords の第三引数に {per_page: -1} 以外に exclude も加えていますが、これは単に一部のカテゴリーを除外しているものです。

getEntityRecords については以下の公式ページが参考になるかと思います。

参考情報
@wordpress/data – Block Editor Handbook | Developer.WordPress.org
@wordpress/core-data – Block Editor Handbook | Developer.WordPress.org

あとがき

ちなみに、ブロックエディタのサイドバーのセレクトボックス( SelectControl )にカテゴリーやカスタムタクソノミーを動的にセットする以前は、WordPress の管理画面でカテゴリーの名前と ID を調べて効率の悪い書き方をしていました(苦笑)。

<SelectControl
	value = { attributes.career }
	options = { [
		{value: '', label: 'キャリアを選択'},
		{value: '18', label: 'NTTドコモ'},
		{value: '19', label: 'au'},
		{value: '20', label: 'SoftBank'},
		{value: '5', label: '楽天モバイル'},
		{value: '8', label: 'ahamo'},
		{value: '7', label: 'LINEMO'},
		{value: '6', label: 'povo'},
		{value: '13', label: 'UQmobile'},
		{value: '9', label: 'Y!mobile'},
		{value: '22', label: 'irumo'},
		{value: '14', label: 'mineo'},
		{value: '4', label: 'IIJmio'},
		{value: '21', label: 'J:COMモバイル'},
		{value: '12', label: 'NUROモバイル'},
		{value: '16', label: 'イオンモバイル'},
		{value: '15', label: 'BIGLOBEモバイル'},
		{value: '17', label: 'HISモバイル'},
		{value: '11', label: 'LIBMO'},
		{value: '10', label: '日本通信'}
	] }
	onChange = { (newCareer) => {
		setAttributes({ career: newCareer });
	}}
/>

まぁ、このような記述でも動作はするのですが、カテゴリーやカスタムタクソノミーが増えた場合のメンテナンスが面倒です。

wp.data.select(‘core’).getEntityRecords(‘taxonomy’, ‘category’) のような記述で取得しておけば、カテゴリーが増えても動的に増えていきますので、メンテナンス性もよくなります。

広告