WordPressのカスタムブロックで、wp_optionsのデータを使う
それっぽい記事があまり見当たらなかったので簡単に覚書。 やりたいこと WordPressのカスタムブロックを作る APIキーを必要とするリクエストを実行する 複数の記事で利用したいので、APIキーはwp_optionsに […]
目次
それっぽい記事があまり見当たらなかったので簡単に覚書。
やりたいこと
- WordPressのカスタムブロックを作る
- APIキーを必要とするリクエストを実行する
- 複数の記事で利用したいので、APIキーはwp_optionsに保存したい
実装(Side PHP)
wp_options
に保存するための設定系ですこし工夫が必要です。
register_settings
でshow_in_rest=>true
を設定する
register_setting
とadd_settings_field
を使って登録画面と処理を実装することが多いと思います。カスタムブロックでの利用を前提とする場合、register_setting
の第三引数でshow_in_rest=>true
を設定しましょう。
/settings
のAPIからこのデータが取れるようになります。ちなみにこのパスはデフォルトで認証必須なので、管理画面外から取り放題になるというわけではありません。
register_setting( 'reading', 'example_api_key', array(
'type' => 'string',
'sanitize_callback' => 'esc_attr',
'show_in_rest' => true,
) );
rest_api_init
フックでもregister_setting
を含む処理を実行する
多くの場合、register_setting
はadmin_init
フックから実行します。が、今回のケースではWP APIからもデータを参照する関係上rest_api_init
フックも利用します。
add_action( 'admin_init', 'example_init_settings_ui' );
add_action( 'admin_init', 'example_init_setting_fields' );
add_action( 'rest_api_init', 'example_init_setting_fields' );
rest_api_init
フックではadd_settings_section
などの管理画面表示系の関数を実行するとFatal Errorがおきます。そのため、「フィールド定義関数(register_setting
)」+「設定画面定義関数 (add_settings_section
/ add_settings_field
)」の2つに分けておくとよいでしょう。
実装(Side JS)
最後にカスタムブロックのJSからの取得です。
@wordpress/core-data
のuseEntityProp
で取得できます。
const { useEntityProp } = require('@wordpress/core-data');
registerBlockType( 'example_block', {
edit: (props) => {
const [apiKey] = useEntityProp( 'root', 'site', 'example_api_key' ))
return (
<AnyAPIProvider apiKey={apiKey}>
...
あまり調べてないのですが、@types/wordpress__core-data
を入れてTypeScriptで実行しようとすると、useEntityProp
が未定義と言われましたので、迷ったら諦めてrequire
しちゃうといいと思います。(解決策わかればリプください。)
注意点: save
には副作用が書けません
なんとなく「saveする時にfetchして更新すればいいやん」という気持ちになりがちなのですが、カスタムブロックではsave
に指定するコンポーネントにuseXXXX
をはじめとする副作用系を書けません。
以下のようにuseState
を書くだけで落ちるので、諦めましょう。
...
save() {
useState()
return (<p>hello</p>)
}
}
Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
ブロック内でfetchしたデータは、以下のように取り回すことになります。
- Edit内データ取得
setAttributes
でブロックのattributesに保存- Save内ではattributesに保存された値を使う