Chaos Tool Suite (ctools)
DrupalにおけるPlugin、Form、AJAX、Context などのユーティリティを提供し、開発者体験を向上させるAPIおよびツールの包括的なスイートです。
ctools
インストール
composer require 'drupal/ctools:^4.1'
composer require 'drupal/ctools:^4.0'
概要
Chaos Tool Suite (ctools) は、主にDrupalでの開発者体験を向上させるために設計されたAPIとツールのセットです。他のモジュールが複雑な機能を構築するために活用できる、強力なユーティリティとヘルパー関数のコレクションを提供します。
CToolsは、マルチステップフォームを作成するためのForm Wizard API、オブジェクトを統一されたラッパーで包むContext API、型付きデータ解決サービス、Blockディスプレイバリアント管理、AJAXモーダルダイアログサポートを提供します。また、制約サポート付きの拡張Conditionプラグインと、複数のページリクエストにまたがるデータのキャッシュのためのTempstoreユーティリティも提供します。
このモジュールは、Panels、Page Manager、および各種Layout Builder拡張機能などの他の主要なDrupalモジュールの依存関係として一般的に使用されます。エンドユーザーは通常、このモジュールに依存するモジュールを通じて間接的にctoolsを利用し、開発者はそのAPIを直接使用して高度な機能を構築します。
Features
- Form Wizard API - 自動的なステップ追跡、前へ/次へナビゲーション、AJAXサポート、リクエスト間で値を保持するためのSharedTempStore統合を備えたマルチステップフォームを作成するための包括的なシステム
- Context API - オブジェクト(Entity、型付きデータ)を統一されたContextラッパーで包み、これらのContextを作成、操作、入力として受け入れるためのAPIを提供するツール
- Typed Data Resolver - 型付きデータの関係を解決し、プロパティパスをContextオブジェクトに変換するサービスで、複雑なEntity関係のナビゲーションを可能にします
- Block Display Variant - 完全なContext認識とリージョン管理を備えたBlockを含み管理するディスプレイバリアントのための抽象基底クラス
- Relationship Plugin System - EntityとTyped Dataプロパティ間の関係を作成・管理するための完全なプラグインマネージャー
- AJAX Modal Dialog Support - AJAX対応のモーダルダイアログとウィザードフォームを簡単に作成するためのTraitとコマンドクラス
- Enhanced Condition Plugins - ContextからBundle制約を適用および削除できる制約サポート付きの拡張EntityBundle Condition
- Tempstore Utilities - 複数のページリクエストにまたがって編集されたオブジェクトをキャッシュするサービスで、複雑なマルチフォーム編集ワークフローを可能にします
- Entity View Block - 任意のEntityタイプを任意の利用可能なView Modeで表示するための動的に生成されるBlock
- Plugin Collection Classes - BlockおよびVariantプラグインのコレクションを管理するためのBlockPluginCollectionとVariantPluginCollection
Use Cases
マルチステップ設定ウィザードの作成
FormWizardBaseクラスを使用してマルチステップ設定フォームを作成します。クラスを拡張し、getOperations()を実装してステップ(各ステップにタイトルとフォームクラス)を定義し、ウィザードコントローラーを使用してルートを設定します。ウィザードは自動的にステップナビゲーション、SharedTempStoreでの値キャッシュ、AJAXモーダルサポートを処理し、カスタマイズ可能な「前へ/次へ/完了」ボタンを提供します。これはPage ManagerやPanelsなどのモジュールで複雑なページ設定を作成するために一般的に使用されます。
EntityフィールドをBlockとして表示
ctools_blockサブモジュールを有効にして、すべてのEntityタイプのフィールドBlockにアクセスできるようにします。これらのBlockは任意のBlockリージョンに配置でき、Contextシステムを使用してEntityの単一フィールドを表示します。Blockインスタンスごとにフォーマッターとラベル表示を設定します。個々のフィールドを独立して配置する必要がある柔軟なレイアウトを作成するのに便利です。
Views Block設定の拡張
ctools_viewsサブモジュールを有効にして、Views Blockを配置する際に追加の設定オプションを取得します。ViewのBlock表示設定で、目的の「設定を許可」オプション(ページあたりのアイテム数、オフセット、ページャータイプ、フィールドの非表示/ソート、フィルターの設定/無効化、ソートの設定)を有効にします。Blockが配置されると、管理者はインスタンスごとにこれらの設定をオーバーライドでき、単一のViewを異なる設定でサイト全体で再利用できます。
Context対応の表示システムの構築
TypedDataResolverとContextMapperサービスを使用して、Entity関係をナビゲートしContext対応の機能を提供するシステムを構築します。リゾルバーは「node:uid:name」のようなトークンスタイルのパスを値を持つ適切なContextオブジェクトに変換できます。これにより、PanelsやPage Managerの機能と同様に、現在のページContextに基づいて適応する動的コンテンツを構築できます。
モーダルダイアログフォームの作成
AjaxFormTraitとOpenModalWizardCommandを使用して、AJAX対応のモーダルダイアログフォームを作成します。TraitはAJAX属性を生成するためのヘルパーメソッドを提供し、コマンドはモーダルダイアログでウィザードフォームを開くことができます。これはフルページリロードを必要としないインライン編集インターフェースや設定ダイアログに便利です。
カスタムRelationshipプラグインの実装
RelationshipInterfaceを実装し、@Relationshipアノテーションを使用してカスタムRelationshipプラグインを作成します。Relationshipは、あるContextから別のContextへのナビゲーション方法を定義します(例: Nodeからその作成者へ)。RelationshipManagerはPlugin/Relationshipディレクトリ内のプラグインを検出します。これは現在のContextに基づいて関連データにアクセスする必要があるシステムを構築するために不可欠です。
Contextへの動的制約の適用
EntityBundleによって実装されるConstraintConditionInterfaceを使用して、Contextに制約を動的に追加または削除します。Conditionが評価されると、Contextの制約を変更できます(例: NodeのContextを特定のコンテンツタイプに制限)。これにより、Condition設定に基づいて適応する柔軟なアクセス制御とコンテンツフィルタリングシステムを構築できます。
プレビュー/一時的なEntityの作成
ctools_entity_maskサブモジュールを有効にし、別のEntityタイプを指す「mask」キーを持つEntityタイプを定義します。マスクEntityはマスクされたタイプからすべてのフィールドと表示設定を継承しますが、データを永続化しないストレージハンドラーを使用します。これはプレビューシステムや、Entityを保存せずにレンダリングする必要がある設定フォームを構築するのに理想的です。
Tips
- FormWizardBaseを拡張する際は、getOperations()をオーバーライドしてウィザードステップを定義します。各ステップにはフォームの完全修飾クラス名を持つ「form」キーと、オプションでステップラベルの「title」キーが必要です。
- ctools.wizard.factoryサービスのgetWizardForm()メソッドで3番目のパラメータをTRUEに設定すると、ウィザードのAJAXモーダルサポートを有効にできます。
- 非推奨のctools.serializable.tempstore.factoryサービスはDrupal Coreのtempstore.sharedサービスに置き換える必要があります。機能は同一です。
- ctools_viewsを使用する場合、Blockを配置する前にViewのBlock表示設定で「設定を許可」オプションを設定してください。有効になった設定のみがBlock設定フォームに表示されます。
- ctoolsのEntityBundle ConditionはCoreのConditionにはない制約サポートを追加します。プログラムでContextにBundle制約を適用する必要がある場合は、applyConstraints()メソッドを使用してください。
- Entity View Blockの場合、再帰保護に注意してください - Entity自体のビュー内でそのEntityを表示しようとすると、無限ループを防ぐためにBlockは空を返します。
- TypedDataResolverのconvertTokenToContext()メソッドは、「node:uid:field_profile:entity」のような深いプロパティパスをナビゲートして、ネストされた関係にアクセスできます。
Technical Details
Hooks 2
hook_ctools_relationship_info_alter
RelationshipManagerによって検出されたRelationshipプラグイン定義をモジュールが変更することを可能にします。
hook_condition_info_alter (used by ctools)
CToolsはこのフックを使用して、CoreのEntity Bundle Conditionクラスを制約をサポートする拡張バージョンに置き換えます。
Troubleshooting 5
ウィザードクラスがgetTempstoreId()とgetMachineName()を適切に実装していることを確認してください。値はこれらの識別子を使用してSharedTempStoreに保存されます。また、フォームのsubmitForm()メソッドがキャッシュされた値を誤って上書きしていないことも確認してください。
ctools_blockサブモジュールを有効にしてください。これらのBlockは意図的にLayout Builderから非表示になっています - 標準のBlock配置インターフェースには表示されますが、Layout BuilderのBlockブラウザには表示されません。
まず、ctools_viewsが有効になっていることを確認してください。次にViewを編集し、Block表示設定に移動します。「設定を許可」で、Block単位で設定したい特定のオプション(ページあたりのアイテム数、オフセット、フィールドの非表示など)を有効にしてください。
ConditionプラグインがConstraintConditionInterfaceを実装していることを確認してください。Conditionを設定した後、Context配列を渡してapplyConstraints()を呼び出します。Conditionが削除または再設定されたときはremoveConstraints()を呼び出すことを忘れないでください。
core/drupal.dialog.ajaxライブラリがアタッチされていることを確認してください。OpenModalWizardCommandはこれを自動的に処理しますが、手動でAJAX呼び出しを使用する場合はライブラリをアタッチする必要があります。また、リンクにAjaxFormTrait::getAjaxAttributes()からの正しいAJAX属性があることも確認してください。
Security Notes 3
- SerializableTempstoreFactoryは非推奨です。セキュリティ監査済みのCoreのSharedTempStoreFactoryに移行してください。
- カスタムウィザードを実装する際は、各ステップに適切なアクセスチェックが設定されていることを確認してください。TempstoreAccessサービスはTempstoreベースのルートへのアクセス検証に役立ちます。
- TypedDataResolverをエンドユーザーに公開してリレーションシップナビゲーションを行う場合は注意してください - 適切に制限されていないと、データ構造情報が漏洩する可能性があります。