From 60883fd61993b9840e1aaae735b082b5369c3e69 Mon Sep 17 00:00:00 2001 From: Akira Tachibana Date: Sun, 26 Nov 2023 00:52:42 +0900 Subject: [PATCH] Translated Extending the Query Loop block --- docs/README.md | 1 + .../extending-the-query-loop-block.md | 330 +++++++++++++++++- docs/japanese-changelog.md | 1 + .../block-api/block-variations.md | 6 +- 4 files changed, 332 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index ceef83589bfa29..e66c779061d1a2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -314,6 +314,7 @@ Everything you need to know to [start contributing to the block editor](/docs/co 2023/11/21 - [削除ボタンの追加](https://ja.wordpress.org/team/handbook/block-editor/how-to-guides/data-basics/5-adding-a-delete-button/) - 翻訳 - [ブロックサポート](https://ja.wordpress.org/team/handbook/block-editor/how-to-guides/block-tutorial/block-supports-in-static-blocks/) - 翻訳 +- [クエリーループブロックの拡張](https://ja.wordpress.org/team/handbook/block-editor/how-to-guides/block-tutorial/extending-the-query-loop-block/) - 翻訳 2023/11/11 - 多数 - JSXを使用しないサンプルの削除 diff --git a/docs/how-to-guides/block-tutorial/extending-the-query-loop-block.md b/docs/how-to-guides/block-tutorial/extending-the-query-loop-block.md index 9be4f3a993d203..16beae7e232619 100644 --- a/docs/how-to-guides/block-tutorial/extending-the-query-loop-block.md +++ b/docs/how-to-guides/block-tutorial/extending-the-query-loop-block.md @@ -1,23 +1,54 @@ + +# クエリーループブロックの拡張 + +クエリーループブロックは強力なツールです。ユーザーが決定した投稿のリストをループし、リスト内の各投稿のコンテキストを継承するブロックの特定セットを表示できます。例えば、あるカテゴリの投稿をすべてループするように設定し、それぞれの投稿のアイキャッチ画像を表示できます。もちろん、それ以外にもさまざまなことが可能です ! + +しかし、クエリーループブロックが非常に強力で自由にカスタマイズ可能な分、面倒な面もあります。ほとんどのユーザーは「クエリー」の概念や関連する専門用語に精通しておらず、クエリループブロックのすべての機能を見せられたくはありません。代わりに、調整する設定が少なく、名前もわかりやすく、あらかじめ設定されたバージョンのブロックの方が遥かに好みです。実際、デフォルトで提供されている、投稿リストのバリエーションはその良い例です。ユーザーは技術的な面に触れることなくクエリーループブロックを使用できるだけでなく、ブロックの目的は見つけやすく、理解しやすくなっています。 + +同じように多くの拡張コンポーネントでも、ブロックの特別なバージョンの表示方法が必要になるかもしれません。たとえば独自のプリセット、追加の設定、ユースケースに無関係なカスタマイズオプションの省略 (たとえば、多くの場合、カスタム投稿タイプ)など。クエリーループブロックにはこのようなバリエーションを作成する、非常に強力な方法があります。 + +## バリエーションを使用したブロックの拡張 + +特定のクエリーループブロック設定を持つ、カスタムブロックバリエーションを登録することで、ベースのクエリーループブロックが提供する機能をすべてそのまま使用しながら、表示方法をより細かく制御できます。ブロックバリエーションの詳細については、[こちら](https://ja.wordpress.org/team/handbook/block-editor/reference-guides/block-api/block-variations/)を参照してください。 + +ブロックバリエーション API を使用すると、ユースケースに最も適切なデフォルト設定を提供できます。 + +さっそくサンプルプログラムを試してみましょう。`book` [カスタム投稿タイプ](https://developer.wordpress.org/plugins/post-types/) を登録するプラグイン用のバリエーションを設定します。 + +### 合理的なデフォルトの提供 + +最初のステップはバリエーションの作成です。バリエーションは設定により、デフォルトで投稿記事の代わりに書籍 (book) のリストを表示するブロックバリエーションを提供します。完全なバリエーションのコードは以下のようになります。 + +```js +const MY_VARIATION_NAME = 'my-plugin/books-list'; +registerBlockVariation( 'core/query', { + name: MY_VARIATION_NAME, + title: 'Books List', + description: 'Displays a list of books', + isActive: ( { namespace, query } ) => { + return ( + namespace === MY_VARIATION_NAME + && query.postType === 'book' + ); + }, + icon: /** SVG アイコンがここに来る */, + attributes: { + namespace: MY_VARIATION_NAME, + query: { + perPage: 6, + pages: 0, + offset: 0, + postType: 'book', + order: 'desc', + orderBy: 'date', + author: '', + search: '', + exclude: [], + sticky: '', + inherit: false, + }, + }, + scope: [ 'inserter' ], + } +); +``` + + +大変に見えるかもしれませんが、心配は不要です。それぞれのプロパティについて、なぜ存在し、何をするのかを見ていきましょう。 + +基本的には、次のようなコードから始める事になります。 + +```js +registerBlockVariation( 'core/query', { + name: 'my-plugin/books-list', + attributes: { + query: { + /** ...必要に応じて、さらにクエリー設定を追加する */ + postType: 'book', + }, + }, +} ); ``` + +このコードによりユーザーはドロップダウンからカスタム `postType` を選択しなくても、正しい構成で表示できます。しかし、ユーザーはどうやってこのバリエーションを発見し、挿入するのでしょうか ? いい質問です ! これを有効にするには、以下を追加します。 + + +```js +{ + /** ... バリエーションのプロパティ */ + scope: [ 'inserter' ], +} ``` + +これによりユーザーがエディターを開き、検索すると、このブロックが他のブロックと同じように表示されます。この時点でバリエーションにカスタムアイコン、タイトル、説明も追加できます。 + +```js +{ + /** ... バリエーションのプロパティ */ + title: 'Books List', + description: 'Displays a list of books', + icon: /* SVG アイコンがここに */, +} +``` + +これでカスタムバリエーションはスタンドアロンブロックとほとんど区別がつかなくなります。プラグインに完全に溶け込み、発見しやすく、ユーザーはドロップインで直接利用できます。 + +### バリエーションのレイアウトのカスタマイズ + +クエリーループブロックは `scope` プロパティとして、文字列 `'block'` をサポートすることに注意してください。理論的にはこれで、ブロック自体を挿入した後に、バリエーションをピックアップできるようになります。ブロックバリエーションピッカーについては[こちら](https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-variation-picker/README.md)を参照してください。 + +しかし現在、この使用は**推奨できません**。これはパターンと `scope: [ 'block' ]` バリエーションを使用したクエリーループの設定のためです。`postType` と `inherit` クエリープロパティを除く、選択されたパターンのすべての属性が使用され、矛盾した機能的でないバリエーションにつながる可能性があります。 + +これを回避するには、2つの方法があります。1つ目は、デフォルトの `innerBlocks` を追加する方法です。 ```js innerBlocks: [ @@ -111,26 +235,57 @@ innerBlocks: [ ], ``` + +バリエーションに `innerBlocks` を含めることで、本質的にクエリーループブロックのセットアップフェーズを提案されたパターンでスキップし、最初のコンテンツとしてこのインナーブロックをブロックに挿入できます。 + +もう一つの方法では、セットアップで提案されるバリエーション固有のパターンを登録し、ブロックのフローを置き換えます。 + +クエリーループブロックは、自身のアクティブなバリエーションの有無、そしてこのバリエーションで利用可能な特定のパターンの有無を判断します。もしあれば、このパターンがユーザーに提案される唯一のパターンになります。オリジナルのクエリーループブロックのデフォルトパターンは含まれません。もしそのようなパターンがなければ、デフォルトのパターンが提案されます。 + +パターンをクエリーループのバリエーションと「接続」するには、パターンの `blockTypes` プロパティに、クエリーループの名前を接頭辞につけたバリエーション名 (例えば `core/query/$variation_name`) を追加する必要があります。パターンの登録についての詳細は[こちら](https://ja.wordpress.org/team/handbook/block-editor/reference-guides/block-api/block-patterns/)を参照してください。 + +もしバリエーションに `innerBlocks` を指定していなければ、セットアップの段階でユーザが「新規」を選択したときに、「接続」バリエーションを提案する方法もあります。これは「接続」パターンと同じ方法で処理されます。クエリーループのアクティブなバリエーションの有無、そして提案する接続されたバリエーションの有無がチェックされます。 + +バリエーションを別のクエリーループのバリエーションに接続するには、`['block']` を値として `scope` 属性を定義し、`namespace` 属性を配列として定義する必要があります。この配列には、接続したいバリエーションの名前 (`name` プロパティ) を含める必要があります。 + +例えば、クエリーループのバリエーションをインサーター (`scope: ['inserter']`) に名前 `products` で公開している場合、`namespace` 属性を `['products']` に設定することで、指定した `block` バリエーションを接続できます。ユーザーが「新規」をクリックした後にこのバリエーションを選択すると、namespace 属性はメインのインサーターのバリエーションによって上書きされます。 + +### Gutenberg のバリエーションの認識 + +このバリエーションを実装した後で気づかれたかもしれませんが、ちょっとした問題が1つあります。バリエーションを挿入している間、ユーザーには透過ですが、Gutenberg は内部でバリエーションをクエリーループブロックとして認識します。たとえばエディターのツリービューではクエリーループブロックとして表示されます。 + +このブロックが実際には特定のバリエーションであることをエディターに伝える方法が必要です。これが `isActive` プロパティが作られた目的です。ブロックの属性に基づいて、特定のバリエーションがアクティブかどうかを判断できます。以下のように使用します。 + +```js +{ + /** ... バリエーションのプロパティ */ + isActive: ( { namespace, query } ) => { + return ( + namespace === MY_VARIATION_NAME + && query.postType === 'book' + ); + }, +} ``` + +`postType` だけを比較すれば良いと思うかもしれません。`postType` が `book` と一致したときに Gutenberg がそのブロックをバリエーションと認識すれば良いと。しかし、これでは網の目が広すぎます。他のプラグインも投稿タイプ `book` のバリエーションを公開するかもしれませんし、ユーザーがエディター設定から手動でタイプを `book` に設定するたびにバリエーションを認識させたくもありません。 + +クエリーループブロックが特別な属性 `namespace` を公開する理由がこれです。この属性はブロックの実装の中では何もしませんが、拡張コンポーネントが自身のバリエーションを認識し、スコープを設定する際に、簡単で一貫性のある方法として使用されます。さらに `isActive` はまた、比較する属性を文字列の配列として受け取ります。多くの場合、`namespace` で十分なため、以下のように使用します。 + +```js +{ + /** ... バリエーションのプロパティ */ + attributes: { + /** ... バリエーションの属性 */ + namespace: 'my-plugin/books-list', + }, + isActive: [ 'namespace' ], +} ``` + +このように、Gutenberg はカスタム名前空間と一致する場合のみ、それが特定のバリエーションであることを認識します ! これはとても便利です ! + +## クエリーの拡張 + +こうした点をすべて踏まえても、カスタム投稿タイプには独自の要件があるかもしれません。フィルタリングしてクエリーしたい特定のカスタム属性をサポートするかもしれませんし、他のクエリーパラメータは無関係だったり、完全にサポートされていないかもしれません。クエリーループブロックはこのようなケースも想定して作成されています。問題の解決方法を見ていきましょう。 + +### 関連性のない、またはサポートされていないクエリーコントロールの無効化 + +カスタム投稿タイプ `book` では、`sticky` 属性をまったく使わず、したがってブロックのカスタマイズにはまったく関係ないとします。ユーザーに何を設定すれば良いかと悩ませず、明確な UX を提供するため、このコントロールを使用できないようにしたいところです。さらに、一般には投稿をデータベースに追加したユーザーを示す `author` フィールドをまったく使わず、代わりにカスタムフィールド `bookAuthor` を使うとします。このとき `author`フィルタを保持することは混乱を招くだけでなく、クエリを完全に「破壊する」ことになります。 + +このためクエリーループブロックバリエーションは、インスペクターのサイドバーに表示するコントロールのキー配列を受け付けるプロパティ `allowedControls` をサポートします。デフォルトでは、すべてのコントロールを受け付けますが、このプロパティに配列を指定し始めるとすぐに、関連するコントロールだけを指定したくなるはずです。 + +Gutenberg バージョン14.2では、以下のコントロールを利用できます。 + + +- `inherit` - テンプレートから直接クエリを継承するためのトグルスイッチを表示する。 +- `postType` - 利用可能な投稿タイプのドロップダウンを表示する。 +- `order` - クエリの順番を選択するドロップダウンリストを表示する。 +- `sticky` - 先頭固定投稿の処理方法を選択するドロップダウンを表示する。 +- `taxQuery` - 現在選択されている投稿タイプで利用可能なタクソノミフィルタを表示する。 +- `author` - 作成者でクエリをフィルタリングするための入力フィールドを表示する。 +- `search` - キーワードでクエリをフィルタリングするための入力フィールドを表示する。 + +この例ではプロパティは以下のようになります。 ```js { @@ -189,14 +408,27 @@ In our case, the property would look like this: } ``` + +上の利用可能なコントロールをすべて非表示にしたければ、`allowedControls` の値として空の配列を設定できます。 + +`postType` コントロールも無効にしていることに注意してください。ユーザーがバリエーションを選択した際、紛らわしい投稿タイプ変更のドロップダウンを表示する理由はありません。その上、カスタムコントロールを実装できるため、ブロックを壊す可能性があります。これについてはすぐ後で見ます。 + +### コントロールの追加 + +プラグインはクエリに必要なカスタム属性を使用するため、たった今無効にしたコアのインスペクタコントロールの代わりに、ユーザーがカスタム属性を選択できるような独自コントロールを追加します。これには、[ブロックフィルター](https://developer.wordpress.org/block-editor/reference-guides/filters/block-filters/)にフックされた [React HOC](https://reactjs.org/docs/higher-order-components.html) 経由で行います。 + +```jsx +import { InspectorControls } from '@wordpress/block-editor'; + +export const withBookQueryControls = ( BlockEdit ) => ( props ) => { + // 私たちのバリエーションである場合にのみ、これらのコントロールを追加したいとします。 + // これには前述の `isActive` 関数と同様、それをチェックするカスタムロジックを + // 実装できます。 + // 以下では、これを処理するカスタム関数 `isMyBooksVariation` を記述したとします。 + return isMyBooksVariation( props ) ? ( + <> + + + { /** カスタムコンポーネント */ } + + + ) : ( + + ); +}; + addFilter( 'editor.BlockEdit', 'core/query', withBookQueryControls ); ``` + +もちろん、コントロールのロジックの実装はあなたの責任です (Gutenberg UI にシームレスにコントロールをフィットさせるには、[`@wordpress/components`](https://www.npmjs.com/package/@wordpress/components) を参考にするとよいでしょう)。ブロック属性内の `query` オブジェクトに追加パラメータを割り当てると、わずかな追加の手間で、ニーズに応じたカスタムクエリを作成できます。 + +現在、フロントエンド側 (つまりエンドユーザー側) でクエリを正しく動かし、エディター側で正しいプレビューを表示するには、少し異なるパスを実装する必要があります。 + +```js +{ + /** ... バリエーションのプロパティ */ + attributes: { + /** ... バリエーションの属性 */ + query: { + /** ... 必要であれば、もっとクエリー設定 */ + postType: 'book', + /** カスタムクエリーパラメータ */ + bookAuthor: 'J. R. R. Tolkien' + } + } +} +``` + +### カスタムクエリをフロントエンド側で動かす + +クエリーループブロックは主に、属性を受け取ってそこからクエリーを構築する、投稿テンプレートブロックを通して機能します。クエリーループブロックの他の重要な子ブロック (ページネーションブロックなど) も同じように動作します。これらはクエリを構築し、フィルター [`query_loop_block_query_vars`](https://developer.wordpress.org/reference/hooks/query_loop_block_query_vars/) を介して、結果を公開します。 + +そのフィルターにフックして、それに応じてクエリを変更できます。ただし他のクエリーループブロックに副作用を引き起こさないようにしてください。少なくとも自分のバリエーションにのみフィルタを適用することを確認してください。 + +```php +if( 'my-plugin/books-list' === $block[ 'attrs' ][ 'namespace' ] ) { + add_filter( + 'query_loop_block_query_vars', + function( $query ) { + /** ここでブロックカスタムクエリパラメータを読み込み、クエリを構築できます。*/ + }, + ); +} ``` + +(上のコードでは、ブロックにアクセスする何らかの方法があることを想定しています。たとえば [`pre_render_block`](https://developer.wordpress.org/reference/hooks/pre_render_block/) フィルター内など。しかし、具体的な解決策はユースケースによって異なる可能性があるため、これは確実な推奨ではありません)。 + +### カスタムクエリーをエディタ側で動かす + +カスタムバリエーションの仕上げとして、カスタムクエリの変更にエディターが反応し、それに応じて適切なプレビューを表示します。これはブロックの機能に必須ではありませんが、ブロックの利用者に対して、完全に統合されたユーザーエクスペリエンスを実現します。 + +クエリーループブロックは、[WordPress REST API](https://developer.wordpress.org/rest-api/) を使用して、プレビューを表示する投稿を取得します。`query` オブジェクトに追加されたパラメータは、API のクエリー引数として渡されます。つまり、これらの追加パラメータは REST API でサポートされるか、カスタム投稿タイプの API リクエストにフックできる [`rest_{$this->post_type}_query`](https://developer.wordpress.org/reference/hooks/rest_this-post_type_query/) フィルターのようなカスタムフィルターで処理する必要があります。 + +```php +add_filter( + 'rest_book_query', + function( $args, $request ) { + /** ここからカスタムパラメータにアクセスできる */ + $book_author = $request->get_param( 'bookAuthor' ); + /** ... カスタムクエリーロジック */ + } +); +``` + +以上で、完全に機能するクエリーループブロックのバリエーションが完成しました ! + +[原文](https://github.com/WordPress/gutenberg/blob/trunk/docs/how-to-guides/block-tutorial/extending-the-query-loop-block.md) \ No newline at end of file diff --git a/docs/japanese-changelog.md b/docs/japanese-changelog.md index 6e6331250f4371..de581fda7009d4 100644 --- a/docs/japanese-changelog.md +++ b/docs/japanese-changelog.md @@ -5,6 +5,7 @@ 2023/11/21 - [削除ボタンの追加](https://ja.wordpress.org/team/handbook/block-editor/how-to-guides/data-basics/5-adding-a-delete-button/) - 翻訳 - [ブロックサポート](https://ja.wordpress.org/team/handbook/block-editor/how-to-guides/block-tutorial/block-supports-in-static-blocks/) - 翻訳 +- [クエリーループブロックの拡張](https://ja.wordpress.org/team/handbook/block-editor/how-to-guides/block-tutorial/extending-the-query-loop-block/) - 翻訳 2023/11/11 - 多数 - JSXを使用しないサンプルの削除 diff --git a/docs/reference-guides/block-api/block-variations.md b/docs/reference-guides/block-api/block-variations.md index a2c1bdd9dee86c..5d2a8aa80bfa09 100644 --- a/docs/reference-guides/block-api/block-variations.md +++ b/docs/reference-guides/block-api/block-variations.md @@ -247,17 +247,17 @@ The solution is to unregister the other variation before registering your variat -`isActive` プロパティはオプションですが、ブロックが挿入された後にブロックバリエーションに関する情報を表示するために使用したいケースがままあります。例えば、この API は `useBlockDisplayInformation` フックで使用され、`BlockCard` や `Breadcrumbs` コンポーネントのように、その場で適切な情報を取得して表示します。 +`isActive` プロパティはオプションですが、ブロックが挿入された後にブロックバリエーションに関する情報を表示するために使用したいケースがあります。例えば、`useBlockDisplayInformation` フックはこの API を使用して適切な情報を取得し、`BlockCard` や `Breadcrumbs` コンポーネントなどに、取得した情報を表示します。 -`isActive` が設定されていないと、エディターはオリジナルのブロックとバリエーションを区別できず、オリジナルのブロック情報が表示されます。 +`isActive` が設定されていなければ、エディターはオリジナルのブロックとバリエーションを区別できず、オリジナルのブロック情報が表示されます。 -このプロパティには、関数か文字列の配列(`string[]`)を使用できます。この関数は `blockAttributes` と `variationAttributes` を取り、バリデーションがアクティブかどうかの決定に使用できます。埋め込みブロックでの主な差別化ポイントは `providerNameSlug` 属性のため、例えば YouTube 埋め込みバリエーションがアクティブかどうかを判断するには、次のようにします。 +このプロパティには、関数か文字列の配列(`string[]`)を使用できます。関数は `blockAttributes` と `variationAttributes` を取り、バリデーションがアクティブかどうかの決定に使用できます。埋め込みブロックでの主な差別化ポイントは `providerNameSlug` 属性のため、例えば YouTube 埋め込みバリエーションがアクティブかどうかを判断するには、次のようにします。 ``` isActive: ( blockAttributes, variationAttributes ) =>