9.14. Viewsとの統合を書く
ViewsモジュールはDrupalエコシステムで広く使われています。コンテンツのリスト、テーブル、ブロック、スライドショー、データエクスポート - これらのコンテンツの断片は通常Viewsで表示されます。コンテンツタイプ、ブロックタイプ、その他のエンティティタイプを使用している場合は、Viewsが自動的にそれらと統合済みであり、Viewsを使用してコンテンツを表示できます。しかし、hook_schema()で作成した独自のデータベーステーブルを使用するカスタムモジュールでは、ViewsモジュールUIでモジュールのデータを表示するためにViewsとの統合を書く必要があります。
Did this helpモジュールとViewsの統合を見てみましょう:
https://www.drupal.org/project/did_this_help
モジュールはデータを保存するための独自のデータベーステーブルを作成します。このテーブルには文字列、ID、日付が含まれるため、Views統合用に異なるハンドラーを定義する必要があります:

最初にMODULENAME.views.incファイルを追加する必要があります。このファイルは自動的に読み込まれるため、ファイルの場所を他で指定する必要はありません。*.views.incファイルではhook_views_data()を実装する必要があります:
<?php
/**
* @file
* Provide views data for did_this_help.module.
*/
/**
* Implements hook_views_data().
*/
function did_this_help_views_data() {
}
この実装では、カスタムモジュールの独自のデータベーステーブルの構造を記述する配列を返す必要があります。
最初の配列キーにデータベーステーブル名を置くところから始めます:
$data['did_this_help'] = [
'table' => [
'group' => t('Did this help?'),
'base' => [
'field' => 'id',
'title' => t('Did this help? entries'),
'help' => t('Contains a list of Did this help? entries.'),
],
],
];
ここでは配列キー $data['did_this_help']にテーブル名を付けたテーブル記述を示しています。複数のデータベーステーブルとの統合を追加する必要がある場合は、$data配列に異なるキーを追加します: $data['did_this_help1'], $data['did_this_help2']。
次に配列'table'の記述が続きます:
group - Views UIでのフィールド選択を容易にするため、同じパーティション内のフィールドをグループ化できます。
base - このテーブルのシリアルIDを示します。後でこのシリアルIDを使用して外部キーでテーブルを結合します。
次に、Viewsで表示したい各フィールドを記述します:
$data['did_this_help']['id']= [
'real field' => 'id',
'title' => t('Did this help? record ID'),
'help' => t('Did this help? record.'),
'field' => [
'id' => 'standard',
],
'sort' => [
'id' => 'standard',
],
'filter' => [
'id' => 'numeric',
],
'argument' => [
'id' => 'numeric',
],
];
real field - 配列キーでエイリアスを使用する場合、実際のフィールド名(データベーステーブルのカラム)を定義できます。1つのDrupalフィールドタイプに対して、リアルフィールドは異なる値を持つことができます。たとえば、LinkフィールドにはTitleとURIの2つの値があります。各値は独自のDBテーブルカラムに対応します。カラム名はフィールド名とプロパティ名(title, uri)で構成されます:

これらのカラム名はLinkモジュールによって自動的に作成されましたが、カスタムモジュールの"real field"では、hook_views_data()で独自のリアルフィールド値を定義する必要があります。
title, help - ViewsモジュールUIの情報です。
次にfield、sort、filter、argumentというハンドラーIDが続きます。ハンドラーはフィールドをフィルタリングおよび表示する方法を定義します。たとえば、日付はDate Formatで表示し、Date Calendar Popupでフィルタリングする必要があります。数値には>、<および=の操作を伴うフィルターが必要で、文字列には文字列長によるフィルターが必要です。
フィールドハンドラー
フィールドハンドラーはSELECTワード以降のSQLクエリ部分の生成を支援します。
DrupalコアのViewsフィールドハンドラーの一覧はこちらで確認できます:
カスタムモジュールでは、数値と文字列には多くの場合standardハンドラーを使用し、日付データにはdateハンドラーを使用します。
たとえば、IDフィールドはフィールドハンドラー"standard"を使用します:
'id' => [
'real field' => 'id',
'title' => t('Did this help? record ID'),
'help' => t('Did this help? record.'),
'field' => [
'id' => 'standard',
],
'sort' => [
'id' => 'standard',
],
'filter' => [
'id' => 'numeric',
],
'argument' => [
'id' => 'numeric',
],
],
ソートハンドラー
ソートハンドラーはViewsで通常のソートと公開ソートを使用するのに役立ちます。ソートハンドラーはORDER BYワード以降のSQLクエリ部分を定義します。
ソートハンドラーの一覧はこちらで確認できます:
フィルターハンドラー
フィルターハンドラーはViewsで通常のフィルター、公開フィルター、コンテキストフィルターを表示するのに役立ちます。フィルターハンドラーはWHEREワード以降のSQLクエリ部分を定義します。
フィルターハンドラーの一覧はこちらで確認できます:
Date Calendarポップアップで日付をフィルタリングするには、ハンドラー"date"を使用できます:
$data['did_this_help']['created'] = [
'title' => t('Created date for Did this help? record'),
'help' => t('Created date for Did this help? record'),
'field' => [
'id' => 'date',
],
'argument' => [
'id' => 'date',
],
'filter' => [
'id' => 'date',
],
'sort' => [
'id' => 'date',
],
];
リレーションシップハンドラー
リレーションシップハンドラーはSQLクエリに結合を追加し、1つのクエリで複数のテーブルからデータを取得するのに役立ちます。
Did this help?モジュールのDBテーブルにはユーザーIDを持つカラムがあります。リレーションシップハンドラーを使用すると、did_this_helpの行とユーザーの間にViews UIでリレーションを追加し、複数のテーブルからデータを表示できます:
$data['did_this_help']['uid'] = [
'title' => t('User ID for Did this help? record'),
'help' => t('User ID for Did this help? record'),
'field' => [
'id' => 'standard',
],
'sort' => [
'id' => 'standard',
],
'filter' => [
'id' => 'numeric',
],
'argument' => [
'id' => 'numeric',
],
'relationship' => [
'title' => t('User'),
'help' => t('The user on which the log entry as written.'),
'base' => 'users_field_data',
'base field' => 'uid',
'id' => 'standard',
],
];
そのために、フィールドにリレーションシップを追加します。結合したいテーブルを指定する"base"値と、このフィールドで結合するために使用するフィールド"base field"を指定します。Views UI用のtitleとhelp、そしてidリレーションシップハンドラーです。リレーションシップタイプの一覧はこちらで確認できます:
ただし、Viewsはさまざまなハンドラーを幅広く提供しています。ハンドラーの基本クラスを継承し、フィールド、フィルター、ソート用の独自のカスタムハンドラーを書くことができます。次の記事ではViewsフィルター用のカスタムハンドラーを書きます。